原型设计模式
概念:是指原型实例指向创建对象的种类,并通过拷贝这些原型创建新的对象,是一种用来创建对象的模式,也就是创建一个对象作为另一个对象的prototype属性。
实现原型模式
方法一:使用 Object.create(prototype, optionalDescriptorObjects)
var vehiclePrototype = {
model:"保时捷",
getModel: function () {
console.log(‘车辆模具是:‘ + this.model);
}
};
var vehicle = Object.create(vehiclePrototype,{
"model":{
value:"法拉利"
}
});
vehicle.getModel();
方法二:使用 prototype
var vehiclePrototype = {
init: function (carModel) {
this.model = carModel || "保时捷";
},
getModel: function () {
console.log(‘车辆模具是:‘ + this.model);
}
};
function vehicle(model) {
function F() { };
F.prototype = vehiclePrototype;
var f = new F();
f.init(model); return f;
}
var car = vehicle(‘法拉利‘);
car.getModel();
原型规则
var arr = [];
arr.a = 1;
所有的引用类型(数组、对象、函数),都有一个_proto_属性(隐式原型),属性值是一个普通的对象;
所有的函数,都具有一个prototype(显式原型),属性值也是一个普通对象;
所有的引用类型(数组、对象、函数),其隐式原型指向其构造函数的显式原型;(obj.proto === Object.prototype);
当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的_proto_(即它的构造函数的prototype)中去寻找;
2.instanceof的底层实现原理,手动实现一个instanceof
instanceof的实现实际上是调用JS的内部函数 [[HasInstance]]
来实现的
实现原理:只要右边变量的 prototype
在左边变量的原型链上即可。因此,instanceof
在查找的过程中会遍历左边变量的原型链,直到找到右边变量的 prototype
,如果查找失败,则会返回 false,告诉我们左边变量并非是右边变量的实例。
var arr = {};
console.log(new_instance_of(arr,Object));
function new_instance_of(leftValue, rightValue){
let rightProto = rightValue.prototype;
leftValue = leftValue.__proto__;
while(true){
if(leftValue === null){
return false;
}
if(leftValue === rightProto){
return true;
}
leftValue = leftValue.__proto__;
}
}
4.实现继承的几种方式以及他们的优缺点
https://www.cnblogs.com/humin/p/4556820.html
原型链继承(推荐指数:★★)
new Animal()
这样的语句之后执行,不能放到构造器中构造继承(推荐指数:★★)
实例继承(推荐指数:★★)
new 子类()
还是子类()
,返回的对象具有相同的效果拷贝继承(推荐指数:★)
组合继承(推荐指数:★★★★)
寄生组合继承(推荐指数:★★★★)
5.至少说出一种开源项目(如Node)中应用原型继承的案例
6.可以描述new一个对象的详细过程,手动实现一个new操作符
// ES5构造函数
let Parent = function (name, age) {
//1.创建一个新对象,赋予this,这一步是隐性的
// let this = {};
//2.给this指向的对象赋予构造属性
this.name = name;
this.age = age;
//3.如果没有手动返回对象,则默认返回this指向的这个对象,也是隐性的
// return this;
};
const child = new Parent();
winter重学前端专栏中原理的描述:
? 以构造器的prototype属性为原型,创建新对象;
? 将this(也就是上一句中的新对象)和调用参数传给构造器,执行;
? 如果构造器没有手动返回对象,则返回第一步创建的新对象,如果有,则舍弃掉第一步创建的新对象,返回手动return的对象。
简单来说就是new过程中会新建对象,此对象会继承构造器的原型与原型上的属性,最后它会被作为实例返回这样一个过程。
// 构造器函数
let Parent = function (name, age) {
this.name = name;
this.age = age;
};
Parent.prototype.sayName = function () {
console.log(this.name);
};
//自己定义的new方法
let newMethod = function (Parent, ...rest) {
// 1.以构造器的prototype属性为原型,创建新对象;
let child = Object.create(Parent.prototype);
// 2.将this和调用参数传给构造器执行
let result = Parent.apply(child, rest);
// 3.如果构造器没有手动返回对象,则返回第一步的对象
return typeof result === ‘object‘ ? result : child;
};
//创建实例,将构造函数Parent与形参作为参数传入
const child = newMethod(Parent, ‘echo‘, 26);
child.sayName() //‘echo‘;
//最后检验,与使用new的效果相同
child instanceof Parent//true
child.hasOwnProperty(‘name‘)//true
child.hasOwnProperty(‘age‘)//true
child.hasOwnProperty(‘sayName‘)//false
7.理解es6 class构造以及继承的底层实现原理
理解?
原理?
类的创建
//定义类
class Person{
// 类的静态方法,相当于Person.test = function(){console.log("类的静态方法");}
static test() {
console.log("类的静态方法");
}
//constructor构造函数
constructor(name,age){
console.log("调用构造函数");
this.name = name;
this.age = age;
}
//类的一般方法,定义在实例对象的原型对象上,相当于Person.prototype.show = function(){console.log("this.name,this.age");}
show(){
console.log(this.name,this.age);
}
}
let person1 = new Person("wzh",25);
console.log(person1);
person1.show();
Person.test();
类的继承
class Child extends Person{
constructor(name,age,sex){
super(name,age); //调用父类构造函数构造子类
this.sex = sex;
}
//重写父类同名函数
show(){
console.log(this.name,this.age,this.sex);
}
}
let child = new Child("wzl",24,"男");
child.show();
本文作者:AlubNoBug
本文链接:https://www.cnblogs.com/AlubNoBug/p/13926684.html
原文:https://www.cnblogs.com/AlubNoBug/p/13926684.html