You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
function isInstanceOf(left, right) {
while (true) {
if (left.__proto__ === null ) {
return false
}
if (left.__proto__ === right.prototype) {
return true
}
left = left.__proto
}
}
isPrototypeOf
测试一个对象是否在另一个对象的原型链上
var a = {}
Object.prototype.isPrototypeOf(a) // true
构造函数
特点:
函数名第一个字母大写
函数体内使用this关键字,代表要生成的对象实例
生成对象的时候必须要用new来调用构造函数
几种对象的创建
工厂模式
function createPerson(name, age) {
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function() {
alert(this.name)
}
return o
}
var a = createPerson('zhang', 13);
var b = createPerson('lisi', 14)
a !== b
function Person (name) {
var o = new Object()
o.sayName = function() {
console.log(name)
}
return name
}
var person = Person('张三')
person.name = '李四'
person.sayName() // 张三
优点:适合一些安全环境
缺点:无法识别对象的原型
几种继承
继承主要靠原型链实现
原型链继承
function Parent() {
this.name = 'zhangsan'
}
Parent.prototype.getName = function() {
console.log(this.name)
}
function Child() {}
Child.prototype = new Parent();
// Child.prototype.constructor = Child // 不修正的话后面实例给原型添加属性则是添加到了Parent原型上
var child1 = new Child()
child1.getName() // zhangsan
child1.constructor.prototype
优点:原型上的方法和属性可以共享。实现简单
缺点:
引用类型的值修改会让所有实例的值修改
创建子类型的实例的时候,不能向父类型传递参数
借用构造函数
function Parent(name) {
this.name = name
}
function Child(name) {
Parent.call(this, name)
}
var person1 = new Child(['zhangsan', 'lisi', 'wang'])
person1.name.push('wang')
var person2 = new Child(['zhangsan', 'lisi'])
person2.name // 'zhangsan', 'lisi'
优点:
可以借助子类型向父类型传递参数
避免引用类型的被所有实例共享
缺点:方法在构造函数中创建,每次都要创建。父类型原型上的方法子类型不能继承
组合继承
function Parent(name) {
this.name = name
this.colors = ['green']
}
Parent.prototype.getName = function() {
console.log(name)
}
function Child(name) {
Parent.call(this, name)
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
Child.prototype.sayColor = function () {
console.log(this.colors);
}
var child1 = new Child('kevin', '18');
child1.colors.push('black');
console.log(child1.name); // kevin
console.log(child1.age); // 18
console.log(child1.colors); // ["red", "blue", "green", "black"]
var child2 = new Child('daisy', '20');
console.log(child2.name); // daisy
console.log(child2.age); // 20
console.log(child2.colors); // ["red", "blue", "green"]
var a = 1 // configurable false,let 和 const、function等一样,只要声明过就是false
delete a // false不会删除
var a = 1
a = 3 // 由于已经声明过了所以还是false
delete a // false 不会删除
b = 2 // configurable true
delete b // true 会删除
原型
通过这个图就概括了
原型规则
原型链
访问对象的属性,从实例一直通过__proto__构成的链条则是原型链
获取原型和实例的关系
instanceof
实现原理:判断左侧的原型链上是否有右侧的原型
实现
isPrototypeOf
测试一个对象是否在另一个对象的原型链上
构造函数
特点:
几种对象的创建
工厂模式
优点:解决了多个相似对象的问题
缺点:没有解决对象识别的问题,实例都指向Object的原型(不像Date,Array一样)
构造函数模式
优点:可以识别对象类型,person1 instanceOf Person // true
缺点:没有封装性,内部方法暴露在全局作用域
原型模式
优点:实例可共享原型对象的方法和属性
缺点:修改原型对象引用类型值的时候导致实例值变化
组合模式
优点:结合了原型模式和构造函数模式的优点。目前使用最广泛的
寄生构造函数模式
优点:当为一些Array等添加方法和属性,不用修改Array的构造函数
缺点:其实和直接声明方法没啥差别
稳妥构造函数模式
没有实例属性,也不引用this对象
优点:适合一些安全环境
缺点:无法识别对象的原型
几种继承
继承主要靠原型链实现
原型链继承
优点:原型上的方法和属性可以共享。实现简单
缺点:
借用构造函数
优点:
缺点:方法在构造函数中创建,每次都要创建。父类型原型上的方法子类型不能继承
组合继承
优点:集成了借用构造函数模式和原型链模式的优点。最常用的模式
缺点:调用两次构造函数,生成了两份实例
原型继承
Object.create的实现
优点:不用创建自定义类型
缺点:包含引用类型的属性值始终都会共享相应的值(对传入的对象进行了一次浅复制)
寄生式继承
缺点:跟借用构造函数一样,每次创建对象都要创建一次方法
寄生组合式继承
优点:只调用了一次构造函数,减少在Parent.prototype上添加不必要的属性,原型链保持不变。可正常使用instanceof等
类的继承
super相当于Parent.call(this)
extends相当于原型继承
总结:
创建对象:
继承:
new
当用new操作符调用构造函数时,经历了如下的过程:
其实就是一个继承,返回的一个构造函数的实例,Object.create其实也是。
模拟实现
由于new是关键字,所以通过objectFactory来实现。
判断是否是对函数应用了new
如果应用了new关键字,根据原理,我们在执行构造函数代码的时候会进行this绑定,所以this其实就是构造函数自己,所以会返回true。如果用函数调用的话this其实是指向window的,所以会返回False。
对象属性类型
数据属性
所有通过new Object或者对象字面量为对象添加属性都是数据属性
访问器属性
必须通过Object.defineProperty等定义的。可以用来实现双向绑定
读取属性配置
getOwnPropertyDescriptor()
扩展
隐形声明全局变量导致configurable属性为false
class
ES6的class的特点:
1、类中定义的方法都是不可枚举的,而ES中原型上的方法是可以枚举的
2、方法或者属性前加上static表示静态的,不被实例继承
3、必须要new调用
4、可以使用get和set
等于ES5
Babel编译后
继承
特点:
关键字后面可以是多种类型
子类可以继承父类的静态属性
是由于class有两条继承链。
相比寄生组合继承多了一个Object.setPrototypeOf(Child, Parent)。可以实现Child instanceof Parent
Babel编译后
The text was updated successfully, but these errors were encountered: