LiuL0703 / blog

https://liul0703.github.io
38 stars 11 forks source link

原型&继承&闭包 #9

Open LiuL0703 opened 6 years ago

LiuL0703 commented 6 years ago

原型

我们创建每一个函数 都有一个prototype属性 该属性指向一个对象 这个对象就是原型 我们创建一个对象时候 可以根据自己的需求 选择性的将一些方法属性通过prototype属性 挂载在原型对象上 而每一个new出来的实例都有一个proto属性 该属性指向构造函数的原型对象 通过这个属性 让实例方法能够访问 到原型对象上的这方法


闭包

当函数可以记住并访问所在的词法作用域时,就产生了闭包,这个函数持有对该词法作用域的引用,这个引用就叫做闭包 闭包本质还是函数,只不过这个函数绑定了上下文环境(函数内部引用的所有变量) 缺点:常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。 作用(使用场景):可以用来管理私有变量和私有方法,将对变量(状态)的变化封装在安全的环境中,使得这些变量不能被外部随意修改,同时又可以通过指定的函数接口来操作。 闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变量不会被垃圾回收机制回收


继承

var c1 = new Cat(); var c2 = new Cat();

c1.name.push('pig'); console.log(c1.name); // ["cat", "dog", "pig"] console.log(c2.name); // ["cat", "dog", "pig"]

c1.other = 'cat'; console.log(c1.other); // cat console.log(c2.name); // animals

 #### 缺点:  引用类型的属性被所有实例共享 一旦修改 会反应在所以实例上   创建子类型实例时 不能向超类型传参  
注:通过原型链实现继承时 不能使用对象字面量创建原型方法 因为会重写整个原型链
+ ### 借用构造函数
```js
function Animals(){
    this.name = ['cat','dog'];
    this.other = 'animals';
}
function Cat(){
    Animals.call(this);
};

var c1 = new Cat();
var c2 =  new Cat();

c1.name.push('pig');
console.log(c1.name);     // ["cat", "dog", "pig"]
console.log(c2.name);    // ["cat", "dog"]

优点:可以在子类型构造函数中向超类型构造函数传参

缺点:方法都在构造函数中定义,每次创建实例都会创建一遍方法 无法实现函数复用

Animals.prototype.sayName = function(){ console.log(this.name); } function Cat(name,age){ // 属性继承 Animals.call(this,name); this.age = age; }

Cat.prototype = new Animals(); Cat.prototype.constructor = Cat(); Cat.prototype.sayAge= function(){ console.log(this.age); };

var c1 = new Cat('Cat1',18); c1.animals.push('pig'); console.log(c1.animals); // ["cat", "dog", "pig"] c1.sayName(); // Cat1 c1.sayAge(); // 18

var c2 = new Cat('Cat2',19); console.log(c2.animals); // ["cat", "dog"] c2.sayName(); // Cat2 c2.sayAge(); // 19

#### 优点:融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式。
#### 缺点:无论什么情况下都会调用两次父类型构造函数 一次是在创建子类型原型时候 另一次是在子类型构造函数内部 子类型中包含全部父类型对象的实例属性 调用子类型构造函数时会重写这些属性
+ ### 寄生式继承
创建一个仅用于封装继承过程的函数 该函数在内部以某种方式来增强对象 最后返回对象
```js
function Animals(orginal){
    var c = Object(orginal);
    c.sayHi = function(){
        console.log('Hi');
    }
    return c;
}

var c = {
    name:'cat',
    others:['cat1','cat2']
}
var cat = Animals(c);
cat.sayHi();    // 'Hi'

缺点:无法做到函数复用

function object(o) { function F() {} F.prototype = o; return new F(); }

function inheritPrototype(child, parent) { var prototype = object(parent.prototype); prototype.constructor = child; child.prototype = prototype; }

// 继承 inheritPrototype(Child, Parent);


#### 优点:集组合继承和寄生继承优点于一身 是实现继承最有效的方式