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


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

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

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 将绑定表达式限制为一个表达式。如果需要多于一个表达式的逻辑,应当使用计算属性。

基础例子

a={{ a }}, b={{ b }}
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 回调。考虑下面例子:

{{fullName}}
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组件的时候,我们常常要像如下代码一样组合它们:


  
  

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



Vue.component('child-component', {
   // 有效,因为是在正确的作用域内
  template: '
Child
', data: function () { return { someChildProperty: true } } })

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

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

我是子组件的标题

只有在父组件没有要分发的内容时才会显示。

父组件模板如下:

我是父组件的标题

这是一些初始内容

这是更多的初始内容

最终渲染的结果为:

我是父组件的标题

我是子组件的标题

这是一些初始内容

这是更多的初始内容

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

子组件:

父组件:


  

这里可能是一个页面标题

主要内容的一个段落。

另一个主要段落。

这里有一些联系信息

最终渲染的结果:

这里可能是一个页面标题

主要内容的一个段落。

另一个主要段落。

这里有一些联系信息


第四组:王芳 互换城市

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

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


    2018-01-25 JavaScript:(a==1 && a==2 && a==3)能输出true么?、 Vue.js计算属性、Vue 组件之间的通信、互换城市、XtraTreeList控件的使用中几个问题_第2张图片
2018-01-25 JavaScript:(a==1 && a==2 && a==3)能输出true么?、 Vue.js计算属性、Vue 组件之间的通信、互换城市、XtraTreeList控件的使用中几个问题_第3张图片
  1. HTML结构:给img设置一个ID,href="javascript:;"可以阻止a标签的默认行为


  2. JavaScript:


    2018-01-25 JavaScript:(a==1 && a==2 && a==3)能输出true么?、 Vue.js计算属性、Vue 组件之间的通信、互换城市、XtraTreeList控件的使用中几个问题_第4张图片
  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还未能成功的被显示到界面上。所以导致了失败。

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