JavaScript中的原型属性和继承
JavaScript中的原型属性和继承对我来说并不清楚 我有一个功能:JavaScript中的原型属性和继承,javascript,prototype,Javascript,Prototype,JavaScript中的原型属性和继承对我来说并不清楚 我有一个功能: function User (name) { this.name = name; } 问题: 1为什么下列一项为假,另一项为真 User.prototype.hasOwnProperty('name'); // false User.hasOwnProperty('name'); // true User.prototype.hasOwnProperty('name'); // false User.hasOwn
function User (name) {
this.name = name;
}
问题:
1为什么下列一项为假,另一项为真
User.prototype.hasOwnProperty('name'); // false
User.hasOwnProperty('name'); // true
User.prototype.hasOwnProperty('name'); // false
User.hasOwnProperty('name'); // true
2以下各项之间有什么区别:
User.constructor;
User.prototype.constructor;
User.constructor;
User.prototype.constructor;
3如果我像这样重写prototype属性,User.constructor和User.prototype.constructor会发生什么情况:
User.prototype = {
changeName: function(newName) {
this.name = newName;
}
};
User.prototype = {
constructor: User,
changeName: function(newName) {
this.name = newName;
}
};
如果我这样覆盖它会怎么样:
User.prototype = {
changeName: function(newName) {
this.name = newName;
}
};
User.prototype = {
constructor: User,
changeName: function(newName) {
this.name = newName;
}
};
4用户是功能还是原型还是什么?以下网站将其称为原型:“以下示例创建了一个原型…”
非常感谢你的回答
1为什么下列一项为假,另一项为真
User.prototype.hasOwnProperty('name'); // false
User.hasOwnProperty('name'); // true
User.prototype.hasOwnProperty('name'); // false
User.hasOwnProperty('name'); // true
prototype对象没有被赋予name属性,并且默认情况下它没有name属性,因为用户不是本地用户,所以这对于prototype是错误的。
构造函数用户是一个函数,您已经将函数的名称定义为User。这是在解释函数对象时设置的。
您确定没有将其与新用户“foo”混淆。hasOwnProperty“name”;//是吗
在最后一种情况下,User的实例有一个name属性,它是由构造函数用户设置的foo
2以下各项之间有什么区别:
User.constructor;
User.prototype.constructor;
User.constructor;
User.prototype.constructor;
构造函数是函数,因为用户是函数。
未定义User.prototype.constructor,但您通常会在用户处引用它。这是以后将作为new User.constructor访问的内容;//使用者
3如果覆盖原型[…],User.constructor和User.prototype.constructor会发生什么情况
在这两种情况下,User.constructor都不会发生任何变化
对于User.prototype.constructor,之前没有定义
因此在第一种情况下仍然没有定义
在第二种情况下设置为User
请注意,在这两种情况下,整个原型现在都指向不同的对象,因此现有实例将看不到这些更改,并且新实例将无法再访问以前的原型链
4用户是功能还是原型还是什么
用户是一个函数,也是一个构造函数。在JavaScript中,如果将使用某些函数构造函数来构建构造实例,我们将它们称为构造函数
看一个更抽象的例子可能会对你有所帮助
// A function `Foo` which will be our Constructor
function Foo(baz) {
this.bar = baz;
}
// notice here we have `Foo.name; // "Foo"`
// Setting up reference to the constructor through the prototype
Foo.prototype.constructor = Foo;
// Setting up reference to some other shared property through the prototype
Foo.prototype.fizz = ['buzz'];
然后使用
var foo = new Foo('hello world');
foo.bar; // "hello world" (own)
foo.fizz; // ["buzz"] (inherited)
foo.constructor; // Foo (inherited)
var bar = new Foo();
foo.fizz === bar.fizz; // true, this is the same Object reference - it is shared
不要害怕在你的控制台上尝试 JS中的所有内容都是对象 因此,函数是一种特殊类型的对象,该类型的对象有一个名为name的属性,这就是User.hasOwnPropertyname返回true的原因。它与同一函数可以创建的用户对象的属性无关。试着叫它别的名字,你会发现情况就是这样 任何对象都源自另一个对象,即它的原型。函数的原型具有构造函数属性和_proto__属性,但没有名称属性。 因此,Ùser.prototype.hasOwnPropertyname`应该返回false
由于原型的所有属性都是派生的,因此您可以执行此User.constructor,即使User.hasOwnPropertyconstructor将返回false,您首先需要了解原型是什么 在Javascript中,几乎所有东西都是对象 编辑谢谢@Mathletics: 基本布尔、数字和字符串不是对象 在Javascript中创建对象时,默认情况下,其原型将是一个对象 因此,如果我这样做:
var obj = {};
console.log(obj.__proto__)
这将产生:
对象{}
暂停:
要了解obj.prototype和obj.\uuuu proto\uuuuu之间的区别,请参考此
下一步是要理解的概念
这就是Javascript中继承的结构。基本上,原型是另一个对象的父对象,从中派生方法和属性
想象一个兔子继承哺乳动物的计划,哺乳动物继承动物。在Javascript原型链中表示这一点如下:
(Rabbit) -> (Mammal) -> (Animal) -> (Object) -> null
代码为:
function Animal(){}
function Mammal(){}
function Rabbit(){}
Mammal.prototype = new Animal();
Rabit.prototype = new Mammal();
如果您能够理解这些概念,您可能会自己找到问题的答案,但我会尽量让它更清楚:
1为什么下列一项为假,另一项为真
User.prototype.hasOwnProperty('name'); // false
User.hasOwnProperty('name'); // true
User.prototype.hasOwnProperty('name'); // false
User.hasOwnProperty('name'); // true
你应该阅读:
从对象派生的每个对象都继承hasOwnProperty方法。此方法可用于确定对象是否具有指定的属性作为该对象的直接属性[…]
这是一种确保您要查找的属性是在对象本身中定义的,而不是在原型链的更深处
相反的例子是:
console.log(User.hasOwnProperty('constructor'));
(Rabbit) -> (Object) -> null
由于构造函数属性在prototype chaing中定义得更深,因此它不是用户对象的自有属性
在您的情况下,名称是在用户对象中定义的属性,但不是在全局对象的上下文中定义的
2以下各项之间有什么区别:
User.constructor;
User.prototype.constructor;
User.constructor;
User.prototype.constructor;
第一个类取用户的构造函数,第二个类取其pro的构造函数
在本例中,键入全局对象
3 User.constructor和
User.prototype.constructor,如果我重写prototype属性,如
这:
请看这个
TL;DR:当你直接访问原型时,你正在打破原型链,创建一个新的原型链。在Rabbit示例中,如果您在某个点执行了以下操作:
Rabbit.prototype = {
// ...
};
您的新原型链将是:
console.log(User.hasOwnProperty('constructor'));
(Rabbit) -> (Object) -> null
因此,在第一个示例中,User.prototype.constructor将生成:
函数对象{}
在第二个示例中,它将产生:
函数用户名
明白了吗
4用户是功能还是原型还是什么
用户是一个对象,其原型是功能对象,其原型是对象对象
绘制它:
(User) -> (Function) -> (Object) -> null
希望我已经说清楚了。Javascript与其他语言不同,Java、ecc.不是基于类的,它不提供任何定义类的方法。实际上,下一个Javascript ES6 Harmony引入了class关键字,但它只是原型继承上的一个语法糖,目前在任何浏览器中都不可用 因此,Javascript通过原型继承实现了aka-OOP面向对象编程。 如果要创建自定义对象,则需要使用定义该对象的函数。例如: var Person=函数{ /** *如果您想使用基于类的语言,那么这就是构造函数 **/ 函数人{} 返回人;
}窗口;如果你要深入研究杂草,重要的是要注意原始布尔、数字和字符串不是对象。它们每个都有对象包装器,但默认情况下它们不是对象。这就是我错过的:“基本上是一个原型…”。但有一点我不明白:console.logUser.prototype;//用户{}//但这应该是对象{}和console.logUser.prototype.constructor;//用户名,但这应该类似于Object,因为上面解释的是父对象。使用您的示例console.log哺乳类动物.prototype可以完美地工作和理解;//Animal{}给出了我期望的结果。User.prototype.constructor是User,至少在Chrome 46中是这样。可能是