观点:这在不同范围内得到相同的对象

时间:2019-04-26 03:11:20

标签: javascript vue.js

我是Vue的新手。我看到了这样的演示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
  {{fullname}}
 </div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
  var app = new Vue({
    el:'#app',
    data:{
      firstName: 'first',
      lastName: 'last'
    },
    computed: {
      fullname: {
        get: function(){
          console.log('getter');
          return this.firstName + this.lastName;
        },
        set: function (newValue) {
          console.log('setter:' + newValue);
          let names = newValue.split(' ')
          this.firstName = names[0]
          this.lastName = names[names.length - 1]
        }
      }
    }
  })

</script>
</body>
</html>

如代码所示,有两个子函数get和set。我认为,这两个函数中的this变量不应相同(因为它们属于不同的作用域)。但是效果很好。有想法吗?

2 个答案:

答案 0 :(得分:1)

以该代码为例。我将在运行时使用Function#call来更改this的值。

function test() {
  console.log(this.firstName);
}

test(); // undefined
test.call({ firstName: "Test1" });

您看到,this值是在执行函数时确定的。这正是Vue也会使用的。从Vue source

value = this.getter.call(vm, vm)

答案 1 :(得分:1)

您有一个很大的误解。 this与范围无关。它与绑定有关。

什么是范围

我们不要使用CS语言,而要用普通话说话一分钟。范围确定天气是否可以访问变量。换句话说,它确定变量的“全局性”和“局部性”。

例如:

let x = 0;

function foo () {
    let y = 0;
}

x既在全局范围内,又在foo()内部。另一方面,y仅在foo()内的范围内,并且在其外部不可访问。

什么是绑定

绑定与范围无关(从程序员的角度来看)*。绑定确定属性属于哪个对象。

例如:

foo = {
    a: function () {},
    b: 0
}

bar = Object.create(foo); // create new instance of object foo

foo.a(); // here the function a() is bound to foo
bar.a(); // here the function a() is NOT bound to foo

let x = bar.b; // here we are NOT accessing foo.b!

this是一种引用对象自己的绑定的机制。当您从属于同一对象的方法中调用该方法时,可以编写this.a()而不是foo.a()bar.a()

所以当然是一样的。它们都绑定到同一对象:fullname

  

*注意:我说的是程序员的观点,因为从编译器编写者的角度编写的javascript规范将范围和绑定的概念合并为上下文(有时称为“作用域”,所以是的,在规范“作用域”中有时并不意味着作用域,而是意味着绑定)