> For the complete documentation index, see [llms.txt](https://heihei12305.gitbook.io/my-underscore/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://heihei12305.gitbook.io/my-underscore/untitled/this/new-bang-ding-he-you-xian-ji.md).

# new绑定和优先级

* **new绑定**

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

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

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

使用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) 来直接进行测试，但是我们可以通过使用 硬绑定 来测试它俩的优先级。
