3.创建对象的方式

2020-07-03  本文已影响0人  原来哥哥是万家灯火

1.字面量方式 缺点是太麻烦

var man = {
    name: '张三',
    age: 20
}

2.工厂模式 缺点是无法体现实例间的内部联系

function personCreator(name, age) {
    return {
        name: name,
        age: age
    }
}

let man = personCreator('张三', 20);

3.构造函数模式 缺点是无法共享方法,浪费内存,相当于每次都要this.run = new Function(...) 。理想是方法共享,属性不共享,具体共享不共享,你能有决定权

function Person(name, age) {
    this.name = name;
    this.age = age;
    
    this.run = function () {
        console.log('i am running')
    }
}

let man = new Person('张三', 20);

4.原型模式 缺点是无法传递参数来初始化;另外所有属性都共享,修改原型上的属性可能导致原型被修改

function Person(name, age) {}

Person.prototype = {
    constructor: Person,
    name: '张三',
    age: 20,
    friends: [],
    run: function () {
        console.log('i am running')
    }
}

let man1 = new Person();
let man2 = new Person();


man1.friends.push('张三丰');

console.log(man2.friends)  // [ '张三丰' ]

为什么是 “可能导致原型被修改” 的原因如下:
当一个对象man,其原型上存在属性man.__proto.friends = []; 时,赋值操作man.friends = ['甲'],会使man拥有一个本地属性friends,并没有影响到原型。但如果不是赋值操作,而是man.friends.push['甲'],因为man并没有friends这个本地属性,所以会从原型链上去找,被写入的数据就是man.__proto.friends。

5.组合模式 构造函数和原型模式结合 稍有点每中不足的是封装不好

function Person(name, age) {
   this.name = name;
   this.age = age;
}

Person.prototype.run = function () {
    console.log('i am running')
}

let man = new Person();

6.动态原型模式,改善了组合模式的封装性

function Person(name, age) {
   this.name = name;
   this.age = age;

    Person.prototype.run = function () {
        console.log('i am running')
    }
}

let man = new Person('张三', 20);

注意,直接对Person.prototype重赋值,会导致原型上的属性和方法丢失

function Person(name, age) {
   this.name = name;
   this.age = age;

    Person.prototype = {
        constructor: Person,
        run: function () {
            console.log('i am running')
        }
    }
}

let man = new Person('张三', 20);
man.run() // TypeError: man.run is not a function

原因请先看new操作符的内部原理

7.寄生构造函数模式 断句应该是寄生-构造函数-模式。其实就是把工厂模式的工厂函数通过new 来调用。

function Person(name, age) {
    let obj = {
        name: name,
        age: age
    }

    obj.run = function () {
        console.log('i am running')
    }
}

let man = new Person('张三', 20);

通常用来拓展一些原生类,而又不对其产生影响,且有较好的语义。了解完new操作符的原理之后,就会知道工厂模式无法反映实例联系的缺点,又回来了

function SpecialArray() {
    let arr = [];

    arr.toUpperString = function () {
        return arr.toString().toUpperCase();
    }

    return arr;
}

let arr = new SpecialArray();
arr.push('hi');
console.log(arr.toUpperString()); // HI

8.稳妥构造函数模式

function PersonCreator(name) {
    let obj = {};
    let age = 24;

    obj.introduceName = function () {
        console.log(`hi, i am called ${name}`)
    }

    obj.introduceAge = function () {
        console.log(`hi, i am  ${age} years old`)
    }

    return obj;
}

let man = PersonCreator('张三');
man.introduceName();
man.introduceAge();

稳妥构造函数模式就是返回稳妥一个对象的模式。一个叫道格拉斯·克罗克福德的人发明了js中的稳妥对象这个概念。是指:没有公共属性,其方法不引用this的对象。
此模式不通过new 调用

上一篇 下一篇

猜你喜欢

热点阅读