__JavaScript中的原型与原型
此图再次显示每个对象都有一个原型。建造师 函数Foo也有自己的__JavaScript中的原型与原型,javascript,prototype,javascript-objects,prototypal-inheritance,Javascript,Prototype,Javascript Objects,Prototypal Inheritance,此图再次显示每个对象都有一个原型。建造师 函数Foo也有自己的\uuuu proto\uuu,即function.prototype, 反过来,也通过其\uuuuu proto\uuuu属性再次引用 对象。原型。因此,重复一下,Foo.prototype只是一个显式的 Foo的属性,它引用b和c对象的原型 \uuu proto\uu和prototype之间有什么区别 该图取自。\uuuuu proto\uuuu是查找链中用于解析方法等的实际对象。prototype是使用新建创建对象时用于构建\
\uuuu proto\uuu
,即function.prototype,
反过来,也通过其\uuuuu proto\uuuu
属性再次引用
对象。原型。因此,重复一下,Foo.prototype只是一个显式的
Foo的属性,它引用b和c对象的原型
\uuu proto\uu
和prototype
之间有什么区别
该图取自。
\uuuuu proto\uuuu
是查找链中用于解析方法等的实际对象。prototype
是使用新建创建对象时用于构建\uuuu proto\uuu
的对象:
( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;
prototype
是函数对象的属性。它是由该函数构造的对象的原型
\uuuu proto\uuu
是对象的内部属性,指向其原型。当前的标准提供了一个等价的对象.getPrototypeOf(O)
方法,尽管事实上的标准\uuuuuuuuuuuuuuuu
更快
通过比较函数的原型
与对象的原型
链,可以找到实例的关系,通过更改原型
可以打破这些关系
function Point(x, y) {
this.x = x;
this.y = y;
}
var myPoint = new Point();
// the following are all true
myPoint.__proto__ == Point.prototype
myPoint.__proto__.__proto__ == Object.prototype
myPoint instanceof Point;
myPoint instanceof Object;
function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true
这里的Point
是一个构造函数,它按程序构建一个对象(数据结构)myPoint
是由Point()
构造的对象,因此Point.prototype
会保存到myPoint.\uuuuuuuu
中。声明函数时会创建prototype属性
例如:
function Person(dob){
this.dob = dob
};
Person.prototype
属性在声明上述函数后在内部创建。
可以向Person.prototype添加许多属性,这些属性由使用new Person()创建的Person实例共享
值得注意的是,默认情况下,Person.prototype
是一个对象
文本(可以根据需要进行更改)
使用new Person()
创建的每个实例都有一个\uuuu proto\uuuu
属性,该属性指向Person.prototype
。这是用于遍历以查找特定对象特性的链
var person1 = new Person(somedate);
var person2 = new Person(somedate);
创建Person
的两个实例,这两个对象可以调用age
方法Person.prototype
作为person1.age
,person2.age
在您问题的上图中,您可以看到Foo
是一个函数对象
,因此它有一个\uuuuu proto\uuuu
链接到函数.prototype
,prototype是对象
的一个实例,并且有一个\uuu proto\uuu
链接到对象.prototype
。proto链接在这里以对象中的\uu proto\uu
结束。prototype
指向null
任何对象都可以访问其由\uuuuu proto\uuuu
链接的原型链中的所有属性,从而形成原型继承的基础
\uuuu proto\uuuu
不是访问原型链的标准方法,标准但类似的方法是使用Object.getPrototypeOf(obj)
下面的instanceof
运算符代码有助于更好地理解:
objectinstanceof
Class运算符在对象是类的实例时返回true
,更具体地说,如果在该对象的原型链中找到Class.prototype
,则该对象是该类的实例
function instanceOf(Func){
var obj = this;
while(obj !== null){
if(Object.getPrototypeOf(obj) === Func.prototype)
return true;
obj = Object.getPrototypeOf(obj);
}
return false;
}
上面的方法可以被称为:instanceOf.call(object,Class)
,如果object是类的实例,它将返回true。考虑它的一个好方法是
原型
由构造函数
函数使用。它应该被称为“prototypeToInstall”
,因为它就是这样
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。不同之处在于,使用下划线命名的函数(如_proto__)根本不适合显式调用的开发人员。换句话说,它们只是用于一些机制,如继承等。它们是“后端”。但不带下划线的函数是为显式调用而设计的,它们是“前端” 理解它的另一个好方法:
var foo={}
/*
构造函数是对象,所以foo.constructor.prototype实际上是
对象原型;作为回报,Object.prototype是foo.\uuuu proto\uuu链接到的对象。
*/
log(foo.constructor.prototype==foo.\uuu proto\uuu);
//这证明了上述评论所宣称的:两种说法的评估结果都是正确的。
log(foo.\uuuu proto\uuuu==Object.prototype);
log(foo.constructor.prototype==Object.prototype);
仅在支持IE11\uuuuuuuuuuuuuuu
之后。在该版本之前,例如IE9,您可以使用构造函数
来获取\uuuuuuuuuuuuuuu
创建函数时,将自动创建一个名为prototype的属性对象(不是您自己创建的)并将其附加到函数对象(构造函数)。
注意:此新的prototype对象还指向或具有指向本机JavaScript对象的内部私有链接
例如:
function Foo () {
this.name = 'John Doe';
}
// Foo has an object property called prototype.
// prototype was created automatically when we declared the function Foo.
Foo.hasOwnProperty('prototype'); // true
// Now, we can assign properties and methods to it:
Foo.prototype.myName = function () {
return 'My name is ' + this.name;
}
如果您使用new
关键字从Foo
创建一个新对象,那么您基本上是在创建一个新对象,该对象具有内部链接或私有链接,链接到我们前面讨论过的函数Foo
的原型:
var b = new Foo();
b.[[Prototype]] === Foo.prototype // true
到该函数对象的private链接称为双括号原型或var b = new Foo();
b.[[Prototype]] === Foo.prototype // true
b.__proto__ === Foo.prototype // true
Object.getPrototypeOf(b) === b.__proto__ // true
function Person(name){
this.name = name
};
var eve = new Person("Eve");
eve.__proto__ == Person.prototype //true
eve.prototype //undefined
> var a = 1
undefined
> a.__proto__
[Number: 0]
> Number.prototype
[Number: 0]
> Number.prototype === a.__proto__
true
function Foo(message){
this.message = message ;
};
console.log(Foo.prototype);
var a = new Foo("a");
var b = new Foo("b");
console.log(a.message);
console.log(b.message);
b.__proto__ === Object.getPrototypeOf(a);
a.__proto__ === Foo.prototype;
a.constructor.prototype === a.__proto__;
Foo.prototype.Greet = function(){
console.log(this.message);
}
a.Greet();//a
b.Greet();//b
a.constructor.prototype.Greet();//undefined
function Foo() { }
var bar = new Foo()
// `bar` is constructed from how Foo knows to construct objects
bar.__proto__ === Foo.prototype // => true
// bar is an instance - it does not know how to create objects
bar.prototype // => undefined
function a (name) {
this.name = name;
}
constructor: a // function definition
__proto__: Object
var b = new a ('JavaScript');
function Person (name, age) {
this.name = name;
this.age = age;
}
var John = new Person(‘John’, 37);
// John is an object
Person.prototype.getOlder = function() {
this.age++;
}
// getOlder is a key that has a value of the function
John.getOlder();
Person.prototype;
var a = { name: "wendi" };
a.__proto__ === Object.prototype // true
Object.getPrototypeOf(a) === Object.prototype // true
function Foo() {};
var b = new Foo();
b.__proto__ === Foo.prototype
b.__proto__.__proto__ === Object.prototype
function Foo() {};
Foo.prototype // Object {constructor: function}
Foo.prototype.constructor === Foo // true
{}.prototype // undefined;
(function(){}).prototype // Object {constructor: function}
// The example above shows object does not have the prototype property.
// But we have Object.prototype, which implies an interesting fact that
typeof Object === "function"
var obj = new Object();
function Foo() {}
var b = new Foo();
b.__proto__ === Foo.prototype // true
Foo.__proto__ === Function.prototype // true
Function.prototype.__proto__ === Object.prototype // true
function Robot(name) {
this.name = name;
}
var robot = new Robot();
// the following are true
robot.__proto__ == Robot.prototype
robot.__proto__.__proto__ == Object.prototype
function Robot(name) {
this.name = name;
}
// imaginary class
class Robot extends Object{
static prototype = Robot.class
// Robot.prototype is the way to add things to Robot class
// since Robot extends Object, therefore Robot.prototype.__proto__ == Object.prototype
var __proto__;
var name = "";
// constructor
function Robot(name) {
this.__proto__ = prototype;
prototype = undefined;
this.name = name;
}
}
var robot = new Robot();
robot.__proto__ == Robot.prototype
robot.prototype == undefined
robot.__proto__.__proto__ == Object.prototype
Robot.prototype.move(x, y) = function(x, y){ Robot.position.x = x; Robot.position.y = y};
// Robot.prototype.move(x, y) ===(imagining)===> Robot.class.move(x, y)
// Swift way of extention
extension Robot{
function move(x, y){
Robot.position.x = x; Robot.position.y = y
}
}
// imaginary class
class Robot{
static prototype = Robot.class // Robot.prototype way to extend Robot class
var __proto__;
var name = "";
// constructor
function Robot(name) {
this.__proto__ = prototype;
prototype = undefined;
this.name = name;
}
// added by prototype (as like C# extension method)
function move(x, y){
Robot.position.x = x; Robot.position.y = y
};
}
function Foo(name){
this.name = name
Foo.__proto__.collection.push(this)
Foo.__proto__.count++
}
Foo.__proto__.count=0
Foo.__proto__.collection=[]
var bar = new Foo('bar')
var baz = new Foo('baz')
Foo.count;//2
Foo.collection // [{...}, {...}]
bar.count // undefined
'use strict'
function A() {}
var a = new A();
class B extends A {}
var b = new B();
console.log('====='); // =====
console.log(B.__proto__ === A); // true
console.log(B.prototype.__proto__ === A.prototype); // true
console.log(b.__proto__ === B.prototype); // true
console.log(a.__proto__ === A.prototype); // true
console.log(A.__proto__ === Function.__proto__); // true
console.log(Object.__proto__ === Function.__proto__); // true
console.log(Object.prototype === Function.__proto__.__proto__); // true
console.log(Object.prototype.__proto__ === null); // true
console.log(a.constructor === A); // true
// "a" don't have constructor,
// so it reference to A.prototype by its ``__proto__`` property,
// and found constructor is reference to A
console.log(Object.getPrototypeOf(a) === a.__proto__); // true
function Dog(){}
Dog.prototype.bark = "woof"
let myPuppie = new Dog()
> myPuppie.__proto__
>> {bark: "woof", constructor: ƒ}
> myPuppie.prototype
>> undefined
( new Foo ).__proto__ === Foo.prototype;
( new Foo ).prototype === undefined;
function Human(){
this.speed = 25;
}
var himansh = new Human();
Human.prototype.showSpeed = function(){
return this.speed;
}
himansh.__proto__ === Human.prototype; //true
himansh.showSpeed(); //25
//now re-initialzing the Human.prototype aka changing its memory location
Human.prototype = {lhs: 2, rhs:3}
//himansh.__proto__ will still continue to point towards the same original memory location.
himansh.__proto__ === Human.prototype; //false
himansh.showSpeed(); //25
let x = {name: 'john'};
let x = new String("testing") // Or any other javascript object you want to create
Object.getPrototypeOf(x) === x.__proto__; // true
var Cat = function() {}
var tom = new Cat()
function protofoo(){
}
var protofoo1 = new protofoo();
console.log(protofoo.prototype.toString()); //[object Object]
var foo={
check: 10
};
console.log(foo.__proto__); // empty
console.log(bar.prototype); // TypeError
foo.__proto__ = protofoo1; // assigned
console.log(foo.__proto__); //protofoo
// we can create `bar` and link it to `foo`
var bar = Object.create( foo );
bar.fooprops= "We checking prototypes";
console.log(bar.__proto__); // "foo"
console.log(bar.fooprops); // "We checking prototypes"
console.log(bar.check); // 10 is delegated to `foo`
let myObject= {
a: 2
};
console.log(myObject.a); // 2
let anotherObject= {
a: 2
};
// create an object linked to anotherObject
let myObject= Object.create(anotherObject);
console.log(myObject.a); // 2
// for..in loop uses [[Prototype]] chain lookup process
let anotherObject= {
a: 2
};
let myObject= Object.create(anotherObject);
for(let k in myObject) {
console.log("found: " + k); // found: a
}
// in operator uses [[Prototype]] chain lookup process
console.log("a" in myObject); // true
let foo= function(){}
console.log(foo.prototype);
// returns {constructor: f} object which now contains all the default properties
foo.id= "Walter White";
foo.job= "teacher";
console.log(foo.prototype);
// returns {constructor: f} object which now contains all the default properties and 2 more properties that we added to the fn object
/*
{constructor: f}
constructor: f()
id: "Walter White"
job: "teacher"
arguments: null
caller: null
length: 0
name: "foo"
prototype: {constructor: f}
__proto__: f()
[[FunctionLocation]]: VM789:1
[[Scopes]]: Scopes[2]
__proto__: Object
*/
{}.prototype; // SyntaxError: Unexpected token '.'
(function(){}).prototype; // {constructor: f}
let Letter= function(){}
let a= new Letter();
Letter.from= "Albuquerque";
Letter.prototype.to= "New Hampshire";
console.log(a.from); // undefined
console.log(a.to); // New Hampshire
Object.defineProperty(Object.prototype, "__proto__", {
get: function() {
return Object.getPrototypeOf(this);
},
set: function(o) {
Object.setPrototypeOf(this, o);
return o;
}
});
let Letter= function() {}
let a= new Letter();
let b= new Letter();
let z= new Letter();
// output in console
a.__proto__ === Letter.prototype; // true
b.__proto__ === Letter.prototype; // true
z.__proto__ === Letter.prototype; // true
Letter.__proto__ === Function.prototype; // true
Function.prototype.__proto__ === Object.prototype; // true
Letter.prototype.__proto__ === Object.prototype; // true