我知道这已被问过几百次,但是,我似乎无法理解prototype
这是我的示例脚本
var config = {
writable: true,
enumerable: true,
configurable: true
};
var defineProperty = function(obj, name, value) {
config.value = value;
Object.defineProperty(obj, name, config);
}
var man= Object.create(null);
defineProperty(man, 'sex', "male");
var person = Object.create(man);
person.greet = function (person) {
return this.name + ': Why, hello there, ' + person + '.'
}
var p=Object.getPrototypeOf(person);
alert(p.sex);//shows male
person.prototype.age=13;//why there is a error said the prototype is undefined? I thought it supposed be man object...
var child=function(){}
child.prototype.color="red";//why this line doesn't show error? both child and person are an object .
alert(child.prototype.color);//shows red
var ch=Object.getPrototypeOf(child);
alert(ch.color);//why it is undefined? it is supposed red.
希望你能给我一些帮助......谢谢。
更新
感谢你们的帮助,根据Elclanrs的回答,以下是我所学到的。
Function
是javascript中的内置对象之一。 3格式创建函数对象是相等的。
var function_name = new Function(arg1, arg2, ..., argN, function_body)
function function_name(arg1, arg2, ..., argN)
{
...
}
var function_name=function(arg1, arg2, ..., argN)
{
...
}
因此,这就是创建原型链的原因,我们必须创建一个函数,然后使用new关键字调用它。
Function.prototype
是对所有函数对象prototype
的引用。
干杯
答案 0 :(得分:12)
prototype
属性仅存在于函数中,person
不是函数。这是一个object
。
以下是发生的事情:
var man = Object.create(null); // man (object) -> null
man.sex = "male";
var person = Object.create(man); // person (object) -> man (object) -> null
person.greet = function () { ... };
var p = Object.getPrototypeOf(person); // man (object) -> null
alert(p.sex); // p is the same object as man
person.prototype.age = 13; // person doesn't have a prototype
var child = function () {}; // child (function) -> Function.prototype
// -> Object.prototype -> null
child.prototype.color = "red"; // child has a prototype
var ch = Object.getPrototypeOf(child); // Function.prototype
alert(ch.color); // ch is not the same as color.prototype
// ch is Function.prototype
有关详情,建议您阅读以下答案:https://stackoverflow.com/a/8096017/783743
修改:用尽可能少的单词解释发生的事情:
JavaScript中的所有内容都是一个对象,除了原始值(布尔值,数字和字符串),以及null
和undefined
。
所有对象都有一个名为[[proto]]
的属性,程序员无法访问该属性。但是,大多数引擎都会将此属性设置为__proto__
。
当您创建var o = { a: false, b: "something", ... }
之类的对象时,o.__proto__
为Object.prototype
。
当您创建var o = Object.create(something)
之类的对象时,o.__proto__
为something
。
当您创建var o = new f(a, b, ...)
之类的对象时,o.__proto__
为f.prototype
。
当JavaScript无法在o
上找到属性时,它会在o.__proto__
然后o.__proto__.__proto__
等上搜索该属性,直到找到该属性或原型链结束为止在null
中(在这种情况下,属性为undefined
)。
最后,Object.getPrototypeOf(o)
返回o.__proto__
而不是o.prototype
- __proto__
存在于所有对象(包括函数)上,但prototype
仅存在于函数中。< / p>
答案 1 :(得分:10)
我认为你可能会混合概念。首先尝试使用经典的原型继承来掌握原型的概念,然后你可以进入所有新的Object
内容。
在JavaScript中,每个对象(数字,字符串,对象,函数,数组,正则表达式,日期......)都有prototype
,您可以将其视为一组常见的方法(函数) 该对象的所有当前和未来实例。
要创建原型链,您必须创建一个函数,然后使用new
关键字调用它以指定它是构造函数。您可以将构造函数视为主要函数,它使用构建对象的新实例所需的参数。
考虑到这一点,您可以扩展本机对象或创建自己的新原型链。这类似于类的概念,但在实践中更强大。
与您的示例类似,您可以编写这样的原型链:
// Very basic helper to extend prototypes of objects
// I'm attaching this method to the Function prototype
// so it'll be available for every function
Function.prototype.inherits = function(parent) {
this.prototype = Object.create(parent.prototype);
}
// Person constructor
function Person(name, age, sex) {
// Common to all Persons
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype = {
// common to all Persons
say: function(words) {
return this.name +'says: '+ words;
}
};
// Student constructor
function Student(name, age, sex, school) {
// Set the variables on the parent object Person
// using Student as a context.
// This is similar to what other laguanges call 'super'
Person.call(this, name, age, sex);
this.school = school; // unique to Student
}
Student.inherits(Person); // inherit the prototype of Person
var mike = new Student('Mike', 25, 'male', 'Downtown'); // create new student
console.log(mike.say('hello world')); //=> "Mike says: hello world"
在较新版本的JavaScript(阅读EcmaScript)中,他们添加了处理对象和扩展对象的新方法。但是这个概念与传统的原型继承有点不同,它似乎更复杂,而且更多关于JS如何在其下工作的知识将有助于真正理解它是如何工作的,而且它在旧版浏览器中不起作用。这就是为什么我建议你从经典模式开始,你可以在互联网上找到准确和丰富的信息。