2018-01-25 JavaScript:(a==1 && a==2 && a==3)能输出true么?、 Vue.js计算属性、Vue 组件之间的通信、互换城市、XtraTreeList控件的使用中几个问题

第一组:刘聪 JavaScript:(a==1 && a==2 && a==3)能输出true么?(转载)

JavaScript:(a==1 && a==2 && a==3)能输出true么?

有人会说,这个问题好奇葩,放在别的语言里,这要是能输出true,估计是见鬼了,但是你别说,放在js中好真有可能。最近在一个人的推特上提了一个问题:
• 问题:Can (a==1 && a==2 && a==3) ever evaluate to true?
• 答案:yes


在这篇文章中,我将解释这段代码的原理:

const a = {
  num: 0,
  valueOf: function() {
    return this.num += 1
  }
};
const equality = (a==1 && a==2 && a==3);
console.log(equality); // true

你可以打开chorme浏览器,然后打开开发者模式,在console中输入这段代码,你就可以看到输出结果([windows]: Ctrl + Shift + J [mac]: Cmd + Opt + J))(????)

有什么窍门呢?

其实也没有,能有的就是js中的两个概念:
• 隐式转换
• object的valueOf函数

隐式转换

注意:这题里面我们用的是==而不是===,在js中==代表的是等于而不是全等,那么就存在变量的隐式转化问题。这就意味着结果会比我们所期望的更多的可能性。

valueOf

JavaScript提供了一种将对象转化为原始值的方法:Object.prototype.valueOf(),默认情况下,返回正在被调用的对象。
我们举个例子:

const a = {
  num: 0
}

我们可以对上述对象使用valueOf方法,他会返回一个对象。

a.valueOf();
// {num: 0}

是不是很酷,我们可以用typeOf来检测一下这个输出结果的类型:

typeof a.valueOf();
// "object"

为了让valueOf可以更方便将一个对象转化成原始值,我们可以重写他,换种说法就是我们可以通过valueOf来返回一个字符串、数字、布尔值等来代替一个对象,我们可以看以下代码:

a.valueOf = function() {
  return this.num;
}

我们已经重写了原生的valueOf()方法,当我们调用valueOf的时候,他会返回a.num。那我们现在运行以下:

a.valueOf();
// 0

我们得到0了,这很合理,因为0就是赋给a.num的值。那我们可以来做几个测试:

typeof a.valueOf();
// "number"

a.num == a.valueOf()
// true

很好,但为什么这个很重要呢?
这很重要,因为当你两种不同类型的遇到相等操作符的时候,js会对其进行类型转化——它企图将操作数的类型转化为类似的。

在我们的问题中:(a==1 && a==2 && a==3)JavaScript会企图将对象转化成数字的类型,进行比较。当要转化的是一个Object的时候,JavaScript会调用valueOf()方法。

自从我们改变了valueOf()方法之后,我们能不能做到以下几点呢:

a == 0
// true

我们做到了,异常轻松。

现在我们需要做的的一点是:当我们每次去调用a的值的时候,能改变它。

幸运的是,在JavaScript中有+=符号。

+=这个运算符可以轻松的去改变一个的值,我们可以举个简单的例子:

let b = 1
console.log(b+=1); // 2
console.log(b+=1); // 3
console.log(b+=1); // 4

正如你所见的,我们每次使用加法赋值运算符,可以让我们的变量增加。
所以我们可以将这个观念用到valueOf()中。

a.valueOf = function() {
  return this.num += 1;
}

当我们每次调用valueOf的时候,他会将变量增加1返回给我们。
随着这个改变,我们来运行下面的代码:

const equality = (a==1 && a==2 && a==3);
console.log(equality); // true

这就是它的工作原理。

记住下面两点:
• 使用相等操作符,js会做强制类型转化
• 我们的对象每次调用valueOf()它的值会增加1

所以比较的时候我们每次都能得到true。
• 补充第二点的运算过程

a                     == 1   -> 
a.valueOf()           == 1   -> 
a.num += 1            == 1   -> 
0     += 1            == 1   ->
1                     == 1   -> true
a                     == 2   -> 
a.valueOf()           == 2   -> 
a.num += 1            == 2   -> 
1     += 1            == 2   ->
2                     == 2   -> true
a                     == 3   -> 
a.valueOf()           == 3   -> 
a.num += 1            == 3   -> 
2     += 1            == 3   ->
3                     == 3   -> true

转载自:https://juejin.im/post/5a63f9a451882573473ddba4


第二组:徐晋 Vue.js计算属性computed与$watch

在模板中绑定表达式是非常便利的,但是它们实际上只用于简单的操作。模板是为了描述视图的结构。在模板中放入太多的逻辑会让模板过重且难以维护。这就是为什么 Vue.js 将绑定表达式限制为一个表达式。如果需要多于一个表达式的逻辑,应当使用计算属性。

基础例子

<div id="example">
    a={{ a }}, b={{ b }}
</div>
var vm = new Vue({
    el: '#example',
    data: {
        a: 1
    },
    computed: {
        // 一个计算属性的 getter
        b: function() {
            // `this` 指向 vm 实例
            return this.a + 1
        }
    }
})

这里我们声明了一个计算属性 b。我们提供的函数将用作属性 vm.b的 getter。

console.log(vm.b) // -> 2
vm.a = 2
console.log(vm.b) // -> 3

你可以打开浏览器的控制台,修改 vm。vm.b 的值始终取决于 vm.a 的值。

你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.b 依赖于 vm.a,因此当 vm.a 发生改变时,依赖于 vm.b 的绑定也会更新。而且最妙的是我们是声明式地创建这种依赖关系:计算属性的 getter 是干净无副作用的,因此也是易于测试和理解的。

计算属性 vs. $watch

Vue.js 提供了一个方法 $watch,它用于观察 Vue 实例上的数据变动。当一些数据需要根据其它数据变化时, $watch 很诱人 —— 特别是如果你来自 AngularJS。不过,通常更好的办法是使用计算属性而不是一个命令式的 $watch 回调。考虑下面例子:

<div id="demo">
    {{fullName}}
</div>
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar',
fullName: 'Foo Bar' } }) vm.$watch('firstName', function (val) { this.fullName
= val + ' ' + this.lastName }) vm.$watch('lastName', function (val) { this.fullName
= this.firstName + ' ' + val })

上面代码是命令式的重复的。跟计算属性对比效果更好:

var vm = new Vue({
    data: {
        firstName: 'Foo',
        lastName: 'Bar'
    },
    computed: {
        fullName: function() {
            return this.firstName + ' ' + this.lastName
        }
    }
})
计算 setter

计算属性默认只是 getter,不过在需要时你也可以提供一个 setter:

// ...
computed: {
    fullName: {
        // getter
        get: function() {
            return this.firstName + ' ' + this.lastName
        },
        // setter
        set: function(newValue) {
            var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1]
        }
    }
}
// ...

现在在调用 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstName 和 vm.lastName 也会有相应更新。


第三组:黄华英 Vue 组件之间的通信

一、非父子组件之间通信

vue中的slot分发内容

当我们在使用vue组件的时候,我们常常要像如下代码一样组合它们:

<app>
  <app-header></app-header>
  <app-footer></app-footer>
</app>

为了让组件可以组合,我们需要一种方式来来混合父组件的内容和子组件的模板,这个过程被叫做内容分发,我们通过<slot>元素作为原始内容的插槽的方式来实现。注意:父组件模板的内容应该就要在父组件 作用域内编译,子组件模板的内容应该在子组件作用域内编译。

<!-- 无效,应为someChildProperty是子组件的属性 -->
<child-component v-show="someChildProperty"></child-component>
Vue.component('child-component', {
   // 有效,因为是在正确的作用域内
  template: '<div v-show="someChildProperty">Child</div>',
  data: function () {
    return {
      someChildProperty: true
    }
  }
})

在进行内容分发的时候子组件至少要有一个slot插槽,否则父组件中的内容将被丢弃。当子组件只有一个slot插槽的时候父组件的所有内容片断都将要插入子组件的slot插槽s所在DOM位子上,并替换掉slot插槽标签本身。

假设子组件模板my-component如下:

<div>
  <h2>我是子组件的标题</h2>
  <slot>
    只有在父组件没有要分发的内容时才会显示。
  </slot>
</div>

父组件模板如下:

<div>
  <h1>我是父组件的标题</h1>
  <my-component>
<!-- 以下内容会进行分发到子组件模板上,如果子组件的模板没有slot插槽,那么内容会被抛弃,如果有一个slot插槽那么以下内容会替换掉slot插槽所在的DOM位子 -->
    <p>这是一些初始内容</p>
    <p>这是更多的初始内容</p>
  </my-component>
</div>

最终渲染的结果为:

<div>
  <h1>我是父组件的标题</h1>
  <div>
    <h2>我是子组件的标题</h2>
    <p>这是一些初始内容</p>
    <p>这是更多的初始内容</p>
  </div>
</div>

如果子组件有多个slot插槽的情况下我们可以通过具名slot将父组件的内容分别分发到子组件的对应名称的slot插槽上面。

子组件:

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

父组件:

<app-layout>
  <h1 slot="header">这里可能是一个页面标题</h1>
  <p>主要内容的一个段落。</p>
  <p>另一个主要段落。</p>
  <p slot="footer">这里有一些联系信息</p>
</app-layout>

最终渲染的结果:

<div class="container">
  <header>
    <h1>这里可能是一个页面标题</h1>
  </header>
  <main>
    <p>主要内容的一个段落。</p>
    <p>另一个主要段落。</p>
  </main>
  <footer>
    <p>这里有一些联系信息</p>
  </footer>
</div>

第四组:王芳 互换城市

过年在携程买票的时候,偶然间发现点击城市中间的图标可以将出发城市和到达城市互换,于是我去官网找了一下实现代码,具体如下:

  1. 效果:点击图标互换城市


  1. HTML结构:给img设置一个ID,href="javascript:;"可以阻止a标签的默认行为


  2. JavaScript:


  3. 源代码:

$("#citySwap").on("click", function () {
    var temp = $("#startCity").val();
    $("#startCity").val($("#endCity").val());
    $("#endCity").val(temp);
    var tempsegnum = $("#startCity").attr("segnum");
    $("#startCity").attr("segnum", $("#endCity").attr("segnum"));
    $("#endCity").attr("segnum", tempsegnum);
})

第五组:王颢 XtraTreeList控件的使用中几个问题

1.repositoryItemComboBox下拉表不能显示

通过repositoryItemComboBox的click事件,向其动态add下拉列表中的items后,点击 repositoryItemComboBox的下拉按钮,下拉列表闪一下就消失了(不是在click事件中添加items的情况,不会出现此问题)。解 决方案,在repositoryItemComboBoxButtonClick事件中,将事件源sender转换为ComboBoxEdit,再利用 add函数添加item,最后手动显示下拉列表,代码如下:

ComboBoxEdit combo = sender as ComboBoxEdit;            combo.Properties.Items.Add(…);
combo.ShowPopup();

2.DevExpress.XtraTreeList设置焦点函数setFocusedNode()无效

当使用TreeListNode addedNode = treeList1.AppendNode(参数略),向tree中添加一个节点后,一 般想立刻使这个新添加的节点获得焦点,但此时如果直接使用treeList1.SetFocusedNode(addedNode)则无效,可能是因为 addedNode中不包含tree为其分配的nodeID(猜测),解决方案是 treeList1.SetFocusedNode(treeList1.FindNodeByKeyID(stateID));即利用findnode之类的函数去查询tree,找到新添加的结点,在将该节点作为SetFocusedNode的参数,则可以完成焦点的设置。

  1. DevExpress.XtraTreeList查找结点函数FindNodeByKeyID()无效

treefind这类函数,在进行查找时,需要注意参数的类型,例如,这个函数FindNodeByKeyID()是根据数据源里的主键进行结点查 找,即你需要给定tree对应数据源中的记录的key,如果数据源中的key是整型,而我们利用一个字符串类型作为参数的 话, FindNodeByKeyID(”100”)将不能找到节点,正确的写法应该是FindNodeByKeyID(100)

WinForm设置控件焦点

winform窗口打开后文本框的默认焦点设置,进入窗口后默认聚焦到某个文本框,两种方法:

①设置tabindex
把该文本框属性里的tabIndex设为0,焦点就默认在这个文本框里了。

②Winform的Activated事件
在Form的Activated事件中添加textBox1.Focus(), 即可获得焦点。

private void Form1_Activated(object sender, EventArgs e) 
{ 
    textBox1.Focus(); 
}

TextBox是可以获得焦点的. 有几个前提:

  1. TextBox所属的窗体(Form)在可操作(Active)状态. 即用户选中了Form.
  2. TextBox的Enable属性,Visiable属性为True.
    刚开始时原以为在Form的Load事件中添加textBox1.Focus(),测试失败
private void Form1_Load(object sender, EventArgs e) 
{ 
    textBox1.Focus(); 
}

因为在窗体加载时调用Focus()函数时, TextBox还未能成功的被显示到界面上。所以导致了失败。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容

  • 这篇笔记主要包含 Vue 2 不同于 Vue 1 或者特有的内容,还有我对于 Vue 1.0 印象不深的内容。关于...
    云之外阅读 5,044评论 0 29
  • Vue 实例 属性和方法 每个 Vue 实例都会代理其 data 对象里所有的属性:var data = { a:...
    云之外阅读 2,198评论 0 6
  • Vue笔记系列1、Vue.js入门3、Vue.js进阶 API 以下会随用随记一些API,可能会不定期更新。 Vu...
    其心阅读 2,053评论 0 10
  • 1.安装 可以简单地在页面引入Vue.js作为独立版本,Vue即被注册为全局变量,可以在页面使用了。 如果希望搭建...
    Awey阅读 10,982评论 4 129
  • 穿梭在钢筋水泥里的人们,我们总是行色匆匆,穿梭在各种场景里。 我们总是拿各种琐碎的事情来当自己忙碌的借口。 印象里...
    snow2011115阅读 180评论 0 1