原型
js的每一个函数都带有一个prototype的属性,这个属性指向一个对象,就叫做原型对象。
对于构造函数来说,可以通过new实例化一个对象,每一个实例化对象都有一个隐含的属性__proto__,这个属性也指向构造函数的原型对象。
原型对象就是一个公共区域,可以被每一个实例化的对象所共用,而不会产生全局变量的污染。
原型的作用就是给实例化的对象提供共享的方法和属性。
//构造函数
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
//给原型增加方法
Person.prototype.sayHi = function(){
console.log("你好!我是" + this.name + "今年" + age + "岁了");
}
Person.prototype.eat = function(){
console.log("我最喜欢吃西瓜");
}
//实例化对象
let p1 = new Person('Tom',12,'男');
let p2 = new Person('Lili',23,'女');
console.log(Person);
/*
ƒ Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
*/
console.log(p1);
/*
Person {name: "Tom", age: 12, sex: "男"}
age: 12
name: "Tom"
sex: "男"
__proto__:
eat: ƒ ()
sayHi: ƒ ()
constructor: ƒ Person(name,age,sex)
__proto__: Object
*/
console.log(Person.prototype);
/*
{sayHi: ƒ, eat: ƒ, constructor: ƒ}
eat: ƒ ()
sayHi: ƒ ()
constructor: ƒ Person(name,age,sex)
__proto__: Object
*/
// A instanceof B 判断A是否是B的实例
console.log(p1 instanceof Person);//true
console.log(p1 instanceof Object);//true 顺着原型链可以找到
console.log(p1 instanceof Array);//false
//A.isPrototypeof(B) B是否是A的实例
console.log(Person.prototype.isPrototypeof(p1));//true
//A.hasOwnProperty(B) A是否有本地属性 B
console.log(p1.hasOwnProperty("name"));//true 是本地属性,通过构造函数
console.log(p1.hasOwnProperty("eat"));//false eat是原型对象上的属性(通过原型添加)
//判断属性是否属于实例 不管是本地还是非本地的属性
console.log('name' in p1);//true
console.log('eat' in p1);//true
原型链
每一个对象都有原型对象,一个原型对象也是一个对象,所以它也有原型对象
当一个对象调用某个方法或者属性的时候,先在自身查找,如果找到就调用,如果没有就顺着__proto__到原型对象中查找,如果还没有就继续取原型的原型中查找,这样形成一条链叫做原型链。
原型链的终点是Object原型,如果还没有找到就返回undefined。
综合上图可以概括出:
1.所有的实例化对象的__proto__指向 其构造函数的prototype。
2.所有普通的对象 和 构造函数的prototype 的__proto__ 都指向 object.prototype。
3.所有函数(包括构造函数)都是function的实例,所以__propo__都指向 function.prototype。
function Fn() {
this.x = 100;
this.y = 200;
this.getX = function () {
console.log(this.x)
}
}
Fn.prototype = {
y:400,
getX: function (){
console.log(this.x)
},
getY: function (){
console.log(this.y)
},
sum:function () {
console.log(this.x + this.y)
}
}
var f1 = new Fn();
var f2 = new Fn();
console.log(f1.getX === f2.getX) // false 先查到了本地属性
console.log(f1.getY === f2.getY) // true 原型上的公共属性
console.log(f1.__proto__.getY === Fn.prototype.getY)// true
console.log(f1.__proto__.getX === f2.getX) // false
console.log(f1.getX === Fn.prototype.getX)// false
console.log(f1.constructor)//ƒ Object() { [native code] }
console.log(Fn.prototype.__proto__.constructor)//ƒ Object() { [native code] }
f1.getX();// 100
f1.__proto__.getX(); // undefined
f2.getY(); //200
Fn.prototype.getY();// 400
f1.sum(); // 300
Fn.prototype.sum();// NaN
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!