我创建了一个简单的类,如下所示:
var Class = function() {};
Class.prototype.testObj = {a:2, b:3};
现在,如果我console.log(Class.testObj)
,我会undefined
。但是,如果我按如下方式创建该类的实例:
var instance = new Class();
console.log(instance.testObj)
我得到预期的输出。
根据我的理解,所有变量都被视为对象并具有原型属性。当在对象中找不到某个键时,遍历原型链以查找键值对。但是在Class的情况下,它不会遍历原型链。
我错过了什么? new
关键字还有哪些附加功能可以访问属性?
答案 0 :(得分:2)
您必须清楚Class()
是constructor
,而不是instance object
。因此Class.testObject
将返回undefined
,因为Class
没有property
。
您可以将prototype
视为对象的配方。几乎每个函数都有一个prototype
属性,用于创建新实例, prototype
在所有对象实例之间共享
构造函数只是一个与new
一起用来创建对象的函数
执行此操作时var instance = new Class();
这意味着您正在创建Class
的实例对象,因此instance
将继承prototype
的{{1}}属性
测试:
Class
答案 1 :(得分:1)
每当你创建一个对象(如函数)时,它都继承自Object构造函数,所以这个
var Class = function() {};
是一个对象,它有自己的prototype
属性,可以使用
Class.prototype
您可以使用
在prototype
对象上创建新属性
Class.prototype.testObj = {a:2, b:3};
如果你想访问它,你实际上必须这样做
console.log(Class.prototype.testObj)
就是这样,一个属性被添加到prototype
的{{1}}属性。
使用Class
关键字时会发生一些神奇的事情,创建一个全新的对象(称为实例),该对象继承自docs
执行代码new Class(...)时,会发生以下情况:
创建一个新对象,继承自Class.prototype。
使用指定的参数调用构造函数Class 和
Class.prototype
绑定到新创建的对象。新类相当于 new Class(),即如果没有指定参数列表,则调用Class 没有争论。- 醇>
构造函数返回的对象成为结果 整个新表达。如果构造函数没有 显式返回一个对象,使用在步骤1中创建的对象 代替。 (通常构造函数不返回值,但如果他们想要覆盖正常的对象创建,他们可以选择这样做 过程)。
答案 2 :(得分:1)
您误解了Class
和Class.prototype
之间的关系。
Class
是一个构造函数。严格来说,JavaScript并没有区分构造函数和通用函数,但这并不重要。 Class.prototype
是Class的实例的原型。也就是说,当您实例化课程时 - var x = new Class()
- Class.prototype
作为委托对象附加到x
。
这意味着对x的查找将向上传播委托链,并在该原型实例上引用变量。
根据我的理解,所有变量都被视为对象并具有原型属性。
这是不正确的。 JavaScript有许多原始类型,只有函数有一个名为' prototype'的属性。原型委托仅在使用带有构造函数的new
或ECMAScript 5 object.create()
表示法创建时附加到引用类型(对象,数组和函数)。
顺便说一句,Class
确实有原型委托,因为它是Function()
的一个实例。委托函数方法的一个实例是apply()
。
答案 3 :(得分:1)
简而言之,Class
不是Class
的实例,它是Function
的实例,为什么它会继承Class.prototype
? Class
&#39}原型链中的第一个链接是Function.prototype
。
我们可以看到,如果我们从Function.prototype
中选择一个函数,例如call
,它就存在于Class
上。
typeof Class.call; //function
对象实例的原型链设置与构造函数的原型。因此,作为Class
实例的nnly对象将使用Class.prototype
设置其原型链。
答案 4 :(得分:0)
您已将对象添加到prototype
,
如果你console.log(Class.prototype)
,你会看到对象。
new
关键字实例化对象,该对象将附加到其原型的属性作为实例化对象的属性。
因为新实例化的对象实际上是继承父对象的prototype
,而不是父对象本身。