new绑定和优先级

  • new绑定

在传统的面向对象的语言中,“构造函数”是类中的一些特殊方法,使用new初始化类时会调用类中的构造函数。但是JavaScript中的new的机制实际上和面向类的语言完全不同。

在JavaScript中,构造函数只是一些使用new操作符时被调用的函数。它们并不会属于某个类,也不会实例化一个类。实际上,它们甚至都不能说是一种特殊的函数类型,它们只是被new操作符调用的普通函数而已。

也即,实际上并不存在所谓的“构造函数”,只有对于函数的“构造调用”。

使用new来调用函数,或者说发生构造函数调用时,会自动执行下面的操作。

  1. 创建(或者说构造)一个全新的对象。

  2. 这个新对象会被执行[[prototype]]连接。

  3. 这个新对象会绑定到函数调用的this。

  4. 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象。

function foo(a){
    this.a = a;
}

var bar = new foo(2);
console.log( bar.a ); //2

使用new来调用foo(...)时,我们会构造一个新对象并把它绑定到foo(...)调用中的this上。new时最后一种可以影响到函数调用时this绑定行为的方法,我们称之为new绑定。

  1. 优先级

毫无疑问,默认绑定的优先级时四条规则中最低的,所以我们可以先不考虑它。

function foo() {
    console.log( this.a );
}

var obj1 = {
    a : 2,
    foo : foo
}

var obj2 = {
    a : 3,
    foo : foo
}

obj1.foo(); // 2
obj2.foo();// 3

obj1.foo.call( obj2 ); // 3
obj2.foo.call( obj1 ); // 2

可以看到,显示绑定优先级更高,也就是说在判断时应当先考虑是否可以存在显示绑定。

function foo(something){
    this.a = something;
}

var obj1 = {
    foo: foo
};

var obj2 = {};

obj1.foo(2);
console.log( obj1.a ) ;//2

obj1.foo.call( obj2, 3);
console.log( obj2.a ) ;//3

var bar = new obj1.foo(4);
console.log( obj1.a ); // 2
console.log( bar.a ); //4

可以看到 new 绑定比隐式绑定优先级高。

new 和 call/apply 无法一起使用,因此无法通过 new foo.call(obj) 来直接进行测试,但是我们可以通过使用 硬绑定 来测试它俩的优先级。

Last updated