Javascript -为什么要循环?(原型属性->构造函数属性->函数对象->构造函数属性)
Javascript - why this loop ? instance->(prototype property->constructor property->function object->constructor property)
我无法理解javascript的这个循环行为。
谁能告诉我为什么要这样设计?这种行为有真正的用例吗?
为什么要循环?{新创建的实例继承构造函数对象的prototype属性。构造函数的Prototype属性是一个保留构造函数属性的对象。构造函数属性等于构造函数对象。再次构造函数对象保持原型属性。}
instance1——inhertis(keeps)——>func()的原型属性——>keep构造函数属性——>函数对象func——>keep原型属性
var func = function(){};
var construct = func.prototype.constructor;
console.log(construct === func); //true
var instance1 = new func();
更新:即使在i赋值之间,instanceof也总是返回true。
var func1 = function(){};
func1.prototype.constructor = 1;
var instance1 = new func1();
console.log(instance1 instanceof func1); //true
var func2 = function(){};
func2.prototype.constructor = 0;
var instance2 = new func2();
console.log(instance2 instanceof func2); //true
很抱歉在一个问题中问两个问题,但这两个问题可能是相关的。
当然它保留了实例。为什么不呢?如果你在做一只鸭子,它就是一只鸭子——它的DNA说它是一只鸭子,不管你把它涂成黑色还是教它做一只鹅。
同样,在您的例子中,设置构造函数没有效果。当你做new func
(或new func()
,它们是相同的)时,你去抓函数的内部属性([[Construct]]
属性),而不是func.prototype.constructor
。
obj.constructor
定义在每个对象上,因为它定义在每个"构造函数"上:也就是说,Object Number Function Date Boolean String
等等。每个原型都有一个constructor
属性:
Object.prototype.constructor === Object;
String.prototype.constructor === String;
//etc
每一个都有自己的prototype.constructor
指向自己。
由于函数也可以像构造函数一样工作,因此它们的.prototype.constructor
属性也指向它们自己。据我所知,这在语言本身中是未使用的。
简洁、专业的答案?http://es5.github.com/x11.8.6
//foo instanceof bar
Return the result of calling the [[HasInstance]] internal method of bar with argument foo.
(稍微转述)
基本上,你是在问鸭妈妈:"对不起,女士,这是你的孩子吗?"这孩子在这件事上几乎没有发言权。编辑:正如评论中提到的,改变原型确实会影响instanceof
的结果。和上面一样,有直观的答案和技术的答案。
直观的答案很简单:原型定义对象。因此,改变原型会改变DNA——你把鸭子变成一只鹅,不是通过教它成为一只鹅,而是通过进入它的DNA,把它变成一只鹅。
技术性是看[[HasInstance]]
做什么。(另一个[[HasIntsance]]
调用这个)规范是非常干燥和简洁的,所以这里是用伪javascript编写的算法:
//assume Func is the function we're talking about
function HasInstance ( value ) {
if ( IsntAnObject(value) ) {
return false;
}
var proto = Func.prototype;
if ( Type(proto) !== "Object" ) {
return false;
}
while ( value !== null ) {
value = value.prototype;
if ( value === proto ) {
return true;
}
}
return false;
}
可以看到,通过改变原型,我们改变了行为- value
将是不同的值
非常好的问题!
由于原型是Object
实例(JavaScript中的所有东西都是),它们必须共享Object
的原型。正好有constructor
属性
实例共享其构造函数原型的所有属性,包括constructor
属性。
指定函数原型的constructor
属性来反映函数本身。例如:
Object.prototype.constructor === Object
Function.prototype.constructor === Function
/* the same with every other function */
当你重写构造函数的原型时,像这样:
Func.prototype = 1
原型本身和Func
的所有实例都有一个不同的constructor
属性,在上面的例子中是Number
。
对于instanceof
,它与constructor
属性本身无关。这与prototype
有关。
function Func() {}
Func.prototype = { a: 1 } // assign a prototype
var fn = new Func() // create an instance
fn instanceof Func // true (reflects connexion to the original prototype)
Func.prototype = { b: 2 } // assign a completely different prototype
fn instanceof Func // false (the connexion is broken)
下面的一小段代码可能会消除您的困惑。正如您所看到的,新实例实际上没有自己的属性"constructor"。因此,当您要求instance.constructor
时,由于原型链接,您实际上获得了instance.prototype.constructor
值。为了保持一致,您希望将instance.constructor
设置为与创建它的函数相同的值。这就是为什么JS解释器将prototype.constructor
设置为函数本身的值。
function Rabbit() { }
var rabbit = new Rabbit()
alert( rabbit.hasOwnProperty('constructor') ) // false
alert( Rabbit.prototype.hasOwnProperty('constructor') ) // true
对于非函数对象也是如此。它们没有自己的。constructor属性,因此调用最终在Object.prototype.constructor
中结束,因此您得到所有非函数对象的相同答案。
constructor
属性设置为函数本身。我不知道答案,但我猜它给语言增加了更多的"活力"。实例。即使您没有创建实例的原始函数,也可以使用构造函数以通用方式创建新实例。function makeUnicorn(animal) {
var unicorn = new animal.constructor();
unicorn.HornOnNose = true;
return unicorn;
}
var unicornRabbit = makeUnicorn(rabbit);
请注意,上面的代码对任何对象运行都没有错误,即使不是函数的实例。你可以使用这个JavaScript特性来定制上述"泛型"函数的行为,如果构造函数是实例的一个自己的属性,你就不能这样做。
Horse.prototype.constructor = function() {
var newHorse = new Horse();
newHorse.Color = "White";
return newHorse;
}
- javascript中对象构造函数中的var属性与this.properties
- Javascript:为什么是构造函数's __proto__属性Empty(){}
- Javascript - 如何向对象构造函数添加属性
- JS构造函数的原型属性与其原型之间的区别
- 属性在我的自定义构造函数中无法正常运行 - Javascript
- 正在重置原型对象的构造函数属性
- 数.[属性] 是对象或构造函数的属性
- 在Javascript构造函数中定义属性的正确方式
- 如何在运行时访问typescript类公共属性(调试)?只有构造函数和函数是可访问的
- 通过程序从构造函数中检索属性名称
- 向构造函数或原型添加属性之间的区别
- Angular 2 Component自定义属性在构造函数中为null
- 使用构造函数创建的数字没有其值作为属性,请取消String与构造函数的链接
- 在定义了构造函数之后,是否可以将实例属性添加到JavaScript原型中
- 在挖空中引用对象构造函数外部视图模型的属性
- Javascript:类构造函数基础 - 在单独的方法中定义属性
- 如何在 JavaScript 中冻结构造函数中的属性
- 在使用函数作为构造函数时,我在初始化属性时卡住了这个运算符.我的代码如下
- 未捕获的类型错误: 无法读取未定义的属性“构造函数”
- Javascript -为什么要循环?(原型属性->构造函数属性->函数对象->构造函数属性)