每日JavaScript -21(声明对象)

声明单个对象,不用说

let obj  = {}
let object = new Object()

但声明多个对象就要一定技巧了
参考文章:
https://github.com/mqyqingfeng/Blog/issues/15
工厂模式

function createPerson(name) {
    var o = new Object();
    o.name = name;
    o.getName = function () {
        console.log(this.name);
    };

    return o;
}

var person1 = createPerson('kevin');

缺点:没法识别对象,每一个实例都指向
构造函数模式

function Person(name) {
    this.name = name;
    this.getName = function () {
        console.log(this.name);
    };
}

var person1 = new Person('kevin');

优点:实例可以被识别

// 不太推荐
alert(person1.constructor == Person)
// 推荐
alert(person1 instanceof Person)

缺点:每个方法都要在每个实例上重新创建一遍。

构造函数模式优化

function Person(name) {
    this.name = name;
    this.getName = getName;
}

function getName() {
    console.log(this.name);
}

var person1 = new Person('kevin');

缺点:没有封装

原型模式

function Person(name) {

}

Person.prototype.name = 'keivn';
Person.prototype.getName = function () {
    console.log(this.name);
};

var person1 = new Person();

优点:方法不会被重新创建

优化

function Person(name) {

}

Person.prototype = {
    name: 'kevin',
    getName: function () {
        console.log(this.name);
    }
};

var person1 = new Person();

优点:提高封装
缺点:重新了原型,缺少constructor属性
优化

function Person(name) {

}

Person.prototype = {
    constructor: Person,
    name: 'kevin',
    getName: function () {
        console.log(this.name);
    }
};

var person1 = new Person();

优点:能通过constructor找到原型
缺点: 1. 所有的属性和方法都共享 2. 不能初始化参数

组合模式

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

Person.prototype = {
    constructor: Person,
    getName: function () {
        console.log(this.name);
    }
};

var person1 = new Person();

优点:属性私有,函数共享
缺点:封装稍差

动态原型

function Person(name) {
    this.name = name;
    if (typeof this.getName != "function") {
        Person.prototype.getName = function () {
            console.log(this.name);
        }
    }
}

var person1 = new Person();

不能使用

Person.prototype = {
  getName: function () {
     console.log(this.name)
  }
}

原因:
new操作符四个步骤:

  1. 创建一个新对象o
  2. o.prot = Object.prototype将新建的对象的_proto_属性指向构建函数的prototype
  3. Object.apply(o)
  4. 返回新对象
    但是第四步有一个原则:如果构造函数Object有返回值,若返回值为基本类型(string, boolean, number, null, undefined, symbol),那么返回新对象。若返回值为对象类型,那么返回该对象。
    所以根据这个规则改善了动态原型模式:
    改进
function Person(name) {
    this.name = name;
    if (typeof this.getName != "function") {
        Person.prototype = {
            constructor: Person,
            getName: function () {
                console.log(this.name);
            }
        }

        return new Person(name);
    }
}

var person1 = new Person('kevin');
var person2 = new Person('daisy');

person1.getName(); // kevin
person2.getName();  // daisy

寄生构造函数模式

function Person(name) {

    var o = new Object();
    o.name = name;
    o.getName = function () {
        console.log(this.name);
    };

    return o;

}

var person1 = new Person('kevin');
console.log(person1 instanceof Person) // false
console.log(person1 instanceof Object)  // true

稳妥构造函数模式

function person(name){
    var o = new Object();
    o.sayName = function(){
        console.log(name);
    };
    return o;
}

var person1 = person('kevin');

person1.sayName(); // kevin

person1.name = "daisy";

person1.sayName(); // kevin

console.log(person1.name); // daisy

es5与es6定义对象的区别
1)class的构造函数必须使用new进行调用,普通构造函数不用new也可执行。
2)class不存在变量提升,es5中的function存在变量提升。
3)class内部定义的方法不可枚举,es5在prototype上定义的方法可以枚举。

https://fed.renren.com/2017/08/07/js-oop-es52es6/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值