Open XXHolic opened 5 years ago
在进行回顾的时候想到了这个,通过查询资料对比了一下,感觉有必要整理一下。
new 操作符创建一个用户定义对象类型或具有构造函数的内置对象的实例。
new
在传统的面向类的语言中,“构造函数”是类中一些特殊方法,使用 new 初始化类时会调用类中的构造函数。JavaScript 中 new 的机制和面向类语言完全不同。JavaScript 中的“构造函数”跟一般函数的唯一区别就是调用的方式不同,实际上并不存在所谓的“构造函数”,只有对于函数的“构造调用”。
在使用 new 来调用函数时,会执行下面的操作:
this
JavaScript 中的对象有一个特殊的 [[Prototype]] 内置属性,是对于其他对象的引用。当在对象中查找属性时,首先检查对象本身是否有这个属性,如果有的话就使用它。如果没有,就会继续访问对象的 [[Prototype]] 链。这个过程会持续到找到匹配的属性名或者查找完整条 [[Prototype]] 链。
所有普通的 [[Prototype]] 链最终都会指向内置的 Object.prototype。由于所有的“普通”(内置,不是特定主机的扩展)对象都“源于” Object.prototype 对象,它包含 JavaScript 中许多通用的功能,比如说 toString() 和 valueOf() 。
toString()
valueOf()
这里主要对 第 2 步进行解释。
function Book(name) { this.name = name; } Book.prototype.printName = function() { console.log("Print book name:",this.name); }; console.info(Book.prototype.constructor === Book); // true var newBook = new Book('How to read'); console.info(newBook.constructor === Book); // true console.info("book name:",newBook.name); newBook.printName();
Book.prototype 默认有一个公有并且不可枚举的属性 constructor ,这个属性引用的是对象关联的函数(这里是 Book)。可以看到通过 new Book() 创建的对象好像有个 constructor 属性,也是指向创建的函数。但不是这样。实际上,constructor 引用同样被委托给了 Book.prototype ,而 Book.prototype.constructor 默认是指向 Book,所以比较的值是 true 。可以把相应的值打印出来看看。
Book.prototype
constructor
Book
new Book()
Book.prototype.constructor
true
console.info("Book.prototype ",Book.prototype); console.info('newBook ',newBook); console.info('newBook.__proto__ ',newBook.__proto__);
可以发现对象 newBook 本身是没有 constructor 属性,而是在 new Book() 过程中将 newBook 内部 [[Prototype]] 关联到 Book.prototype 上。
newBook
再回过头来看,就可以发现并没有所谓的“构造函数”,constructor 在语义上很容易造成误解,需要记住的是“ constructor 并不表示被构造”。
目录
想法
在进行回顾的时候想到了这个,通过查询资料对比了一下,感觉有必要整理一下。
作用
new
操作符创建一个用户定义对象类型或具有构造函数的内置对象的实例。在传统的面向类的语言中,“构造函数”是类中一些特殊方法,使用
new
初始化类时会调用类中的构造函数。JavaScript 中new
的机制和面向类语言完全不同。JavaScript 中的“构造函数”跟一般函数的唯一区别就是调用的方式不同,实际上并不存在所谓的“构造函数”,只有对于函数的“构造调用”。在使用
new
来调用函数时,会执行下面的操作:this
。prototype
JavaScript 中的对象有一个特殊的 [[Prototype]] 内置属性,是对于其他对象的引用。当在对象中查找属性时,首先检查对象本身是否有这个属性,如果有的话就使用它。如果没有,就会继续访问对象的 [[Prototype]] 链。这个过程会持续到找到匹配的属性名或者查找完整条 [[Prototype]] 链。
所有普通的 [[Prototype]] 链最终都会指向内置的 Object.prototype。由于所有的“普通”(内置,不是特定主机的扩展)对象都“源于” Object.prototype 对象,它包含 JavaScript 中许多通用的功能,比如说
toString()
和valueOf()
。示例
这里主要对 第 2 步进行解释。
Book.prototype
默认有一个公有并且不可枚举的属性constructor
,这个属性引用的是对象关联的函数(这里是Book
)。可以看到通过new Book()
创建的对象好像有个constructor
属性,也是指向创建的函数。但不是这样。实际上,constructor
引用同样被委托给了Book.prototype
,而Book.prototype.constructor
默认是指向Book
,所以比较的值是true
。可以把相应的值打印出来看看。可以发现对象
newBook
本身是没有constructor
属性,而是在new Book()
过程中将newBook
内部 [[Prototype]] 关联到Book.prototype
上。再回过头来看,就可以发现并没有所谓的“构造函数”,
constructor
在语义上很容易造成误解,需要记住的是“constructor
并不表示被构造”。参考资料