美文网首页
3.创建对象的方式

3.创建对象的方式

作者: 原来哥哥是万家灯火 | 来源:发表于2020-07-03 12:46 被阅读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 调用

    相关文章

      网友评论

          本文标题:3.创建对象的方式

          本文链接:https://www.haomeiwen.com/subject/bghsqktx.html