注册

前端必须要了解的一些知识 (七)

创建对象又几种方法
//第一种:字面量
var o1 = {name: 'o1'};
var o2 = new Object({name: 'o2'});
//第二种 通过构造函数
var M = function (name) { this.name = name; };
var o3 = new M('o3');
//第三种 Object.create
var p = {name: 'p'};
var o4 = Object.create(p);



o4.__proto__===p//true

原型 构造函数 实例 原型链



instanceof的原理


严谨来判断用constructor
instanceof 并不是很严谨


new运算符背后的原理
原理如下
测试如下

----
面向对象
类与实例
类的声明
1,构造函数
fn Animal(){
this.name = 'name'
}
2,ES6class的声明
class Animal2 {
//↓↓构造函数
constructor(){
this.name=name
}
}
实例化类
console.log(new Animal(),new Animal2())



类与继承
继承的本质就是原型链
继承有几种形式各种的优缺点不同点
1借助构造函数实现继承
fn parent1(){
this.name= 'parent1'
}
parent1.prototype.say(){
console.log('hello')
}
fn child1() {
parent1.call(this)
this.type='child1'
}


缺点 继承后parent1原型链上的东西 继承不say 并没有被继承 只能实现部分继承
如果方法都在构造函数上就能继承
2借助原型链实现继承
fn parent2(){
this.name= 'parent2'
this.play=[1,2,3]
}
fn child2() {
this.type='child2'
}
child2.prototype = new parent2()
var s1 = new Child2();
var s2 = new Child2();
s1.play.push(4);


缺点:如下 引用类型 不同的实例会全部变

3组合方式
前两种的方式的结合
fn parent3(){
this.name= 'parent3'
this.play=[1,2,3]
}
fn child3() {
parent3.call(this)
this.type='child2'
}
child3.prototype = new parent3()
var s3 = new Child3();
var s4 = new Child3();
s3.play.push(4);
console.log(s3.play,s4.play)


缺点:实例化的时候父构造函数执行了两次
//优化方式
fn parent4(){
this.name= 'parent4'
this.play=[1,2,3]
}
fn child4() {
parent4.call(this)
this.type='child4'


}
child4.prototype = parent4.prototype
var s5 = new Child4();
var s6 = new Child4();
console.log(s5 instance child4,s5 instance parent4)//true true
console.log(s5.constructor)//parent4
缺点:区分不了s5是child4还是parent4的实例
//优化方式
fn parent5(){
this.name= 'parent5'
this.play=[1,2,3]
}
fn child5() {
parent5.call(this)
this.type='child5'
}
child5.prototype = Object.creat(parent5.prototype)
//此时还是找不到 创建一下constructor可解决
child5.prototype.constructor = child5
var s7 = new Child5();
console.log(s7 instance child4,s7 instance parent4)//true true
console.log(s7.constructor)//child5


0 个评论

要回复文章请先登录注册