什么是js原型?
在js中创建对象是通过构造函数来完成的
构造函数?
在js中构造函数就相当于一个普通函数,只不过构造函数的命名通常首字母大写
function Person(){ }
构造函数中this指向的是利用构造函数新建的对象
function Person(){ this.name="koko"; this.age=18; }
普通函数可以直接调用,而构造函数需要通过new关键字调用,创建一个对象
var per = new Person();
通过this.name="koko"的方式,使得每一个对象的name值都为koko
如果想不写死,动态的决定每一个对象的name,这就需要参数了,让对象调用构造函数时,自己决定,自己传值
function Person (name,age) { this.name=name; this.age=age; } var per = new Person("jerry",21);
(per.__proto==Person.prototype)
true
我们知道每个函数都有一个 prototype 属性,指向函数的原型。
因此当我们拿到一个函数的时候,就可以确定函数的原型。
反之,如果给我们一个函数的原型,我们怎么知道这个原型是属于哪个函数的呢?
这就要提到原型的 constructor 属性了。
在默认情况下,所有原型对象都会自动获得一个 constructor (念作:构造函数)属性,也就是说每个原型都有都有一个 constructor 属性。
这个属性包含一个指向 prototype 属性所在函数的指针,指向了原型所在的函数。
比如:Person.prototype.constructor 指向 Person。
也就是构造函数的原型的构造函数,指向构造函数。
如何判断一个对象与原型是否存在关系?
当我们想要确定一个对象实例和某个原型之间是否存在关系时,我们有一些方法可以判断,我们可以通过 isPrototypeOf()
方法判断某个原型和对象实例是否存在关系
或者,我们也可以使用 ES5 新增的方法 Object.getPrototypeOf()
获取一个对象实例 __proto__
属性的值。
console.log(Person.prototype.isPrototypeOf(person1)); // true
console.log(Object.getPrototypeOf(person1) == Person.prototype); // true
向原型对象中加入属性和方法的方式
Person.prototype.age = '20';
Person.prototype.sayName = function() { console.log(this.name); }
不能通过字面量的方式加入,因为字面量的方式会创建一个新的对象
Person.prototype = { constructor: Person, name: "Nicholas", age: 29, job: "Software Engineer", sayName: function () { console.log(this.name); } }; person.sayName(); // error
也就是说这里的 Person.prototype
是一个新的对象,和 person
的 __proto__
属性不再有任何关系了
原型的原型:
//Person构造函数 function Person() { this.age = '20'; } //向Person的原型中添加一个属性weight Person.prototype.weight = '120'; //Engineer构造函数 function Engineer() { this.work = 'Front-End'; } //把Engineer的原型变成Person的实例对象
//也就是说,Engieer的原型的原型是Person
//这也是用继承的方式 Engineer.prototype = new Person();
原型链:
按照名字就可以知道,就是原型之间形成的一个链条。
那么原型链的末端又是什么呢?
是 Object ,因此默认原型都会包含一个内部指针,指向 Object.prototype
。
console.log(Person.prototype.__proto__ == Object.prototype); // true
那 Object.prototype
又是什么呢,是 null