在这之前可以先学习一下原型的知识:探究JS的原型.
自定义对象的原型设置
自定义了个父子对象,可以看到儿子的原型是指向Object构造函数的:
let son = {
name: 'son'
};
let father = {
name: 'father',
myFn() {
console.log(`${this.name}调用了father对象内的myFn方法`);
}
};
console.log(son);
修改儿子的原型,而且儿子也可以使用父亲的myFn方法,顺便获取son的原型对象:
let son = {
name: 'son'
};
let father = {
name: 'father',
myFn() {
console.log(`${this.name}调用了father对象内的myFn方法`);
}
};
// 通过setPrototypeOf方法将son对象的原型修改为father
Object.setPrototypeOf(son, father);
console.log(son);
son.myFn();
// Object.getPrototypeOf()获取原型对象。
console.log(Object.getPrototypeOf(son));
检测原型链
instanceof
let son = {
name: 'son'
};
// 检测son的原型链上是否有Object.prototype原型对象
console.log(son instanceof Object); // true
function User(name) {
this.name = name
}
let pyy = new User('彭于晏');
console.log(pyy instanceof User); // true
console.log(User.prototype instanceof Object); // true
isPrototypeOf()
let a = {};
let b = {};
// 检测a.__proto__是否在b对象的原型链上
console.log(a.__proto__.isPrototypeOf(b)); // true
function User() {}
let user = new User();
console.log(User.prototype.isPrototypeOf(user)); // true
console.log(Object.prototype.isPrototypeOf(User.prototype)); // true
console.log(Object.prototype.isPrototypeOf(user)); // true
in 和 hasOwnProperty 属性检测差异
hasOwnProperty用于检测属性是否在该对象中,而in不仅可以检测是否在该对象中,还可以检测是否在存在于原型链的中
let a = {
url: 'CSDN'
};
let b = {
name: '彭于晏'
};
console.log('url' in a); // true
// 给Object添加web属性,也可以检测到a的原型链上存在web属性
Object.prototype.web = 'csdn,net'
console.log('web' in a); // true
console.log(b.hasOwnProperty('name'));
// 虽然Object也在b的原型链上,但是检测不到
console.log(b.hasOwnProperty("web"));
call()继承
构造函数继承父类属性
function Father(name, age) {
this.name = name;
this.age = age;
}
function Son(age, name, score) {
// 调用父构造函数,用call方法
// 第一个参数是将调用Father的this指向自己,也就是Son函数
// 然后就是传参
Father.call(this, name, age);
this.score = score;
};
let son = new Son(18, 'pyy', 100)
console.log(son); // Son {name: "pyy", age: 18, score: 100}
构造函数继承父类方法
方法1:利用父类新创建实例对象
function Father(name, age) {
this.name = name;
this.age = age;
}
// 父构造函数定义方法
Father.prototype.work = function() {
console.log('我要上班');
}
function Son(age, name, score) {
Father.call(this, name, age);
this.score = score;
};
// 子构造函数原型对象指向父构造函数新创建的实例对象。
Son.prototype = new Father();
// 要讲Son.prototype的constructor重新指回Son
Son.prototype.constructor = Son;
// 子构造函数定义方法
Son.prototype.exam = function() {
console.log('我要考试');
}
let son = new Son(18, 'pyy', 100);
let father = new Father(40, 'pyy爸爸');
son.work(); // 我要上班
son.exam(); // 我要考试
father.work(); // 我要上班
father.exam(); // father.exam is not a function
方法二:改变对象原型指向:
function Pyy() {
name: '彭于晏'
};
Pyy.prototype.showPyyName= function() {
console.log('彭于晏');
}
function Wyz() {
name: '吴彦祖'
};
prototype.showWyzName= function() {
console.log('吴彦祖');
};
// 使Pyy对象能够继承Wyz
Pyy.prototype.__proto__ = Wyz.prototype;
let pyy = new Pyy();
// 继承之后,pyy可以调用Wyz的函数
pyy.showWyzName();
// pyy对象的原型链上也有Wyz.prototype的原型对象
console.log(pyy instanceof Wyz);
在还没继承之前:
Pyy.prototype.proto 原本是指向Object.prototype的,继承以后,指向了Wyz.prototype,所以原型链也随之发生变化,pyy调动showWyzName()方法,在自己身上找不到,就去Pyy.prototype那找,再找不到就去Wyz.prototype那找,找到了就调用!