www.qjdy.com-奇迹赌场 > 佳美特设计 > 但是注意

原标题:但是注意

浏览次数:85 时间:2019-11-14

JavaScript 深远之创建对象的有余格局以致优劣势

2017/05/28 · JavaScript · 对象

初藳出处: 冴羽   

写在前头

那篇小说讲明创建对象的各类方法,以致优短处。

但是注意:

那篇小说更像是笔记,因为《JavaScript高等程序设计》写得真是太好了!

1. 厂子方式

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

1
2
3
4
5
6
7
8
9
10
11
function createPerson(name) {
    var o = new Object();
    o.name = name;
    o.getName = function () {
        console.log(this.name);
    };
 
    return o;
}
 
var person1 = createPerson('kevin');

缺陷:对象不可能识别,因为具有的实例都针对二个原型

2. 构造函数情势

function Person(name) { this.name = name; this.getName = function () { console.log(this.name); }; } var person1 = new Person('kevin');

1
2
3
4
5
6
7
8
function Person(name) {
    this.name = name;
    this.getName = function () {
        console.log(this.name);
    };
}
 
var person1 = new Person('kevin');

亮点:实例能够辨别为叁个特定的体系

症结:每一次创制实例时,各个方法都要被创立二次

2.1 构造函数格局优化

function Person(name) { this.name = name; this.getName = getName; } function getName() { console.log(this.name); } var person1 = new Person('kevin');

1
2
3
4
5
6
7
8
9
10
function Person(name) {
    this.name = name;
    this.getName = getName;
}
 
function getName() {
    console.log(this.name);
}
 
var person1 = new Person('kevin');

优点:消释了种种方法都要被再度创建的难点

劣势:那叫什么封装……

3. 原型形式

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

1
2
3
4
5
6
7
8
9
10
function Person(name) {
 
}
 
Person.prototype.name = 'keivn';
Person.prototype.getName = function () {
    console.log(this.name);
};
 
var person1 = new Person();

亮点:方法不会另行创建

破绽:1. 具有的品质和形式都分享 2. 无法起先化参数

3.1 原型形式优化

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

1
2
3
4
5
6
7
8
9
10
11
12
function Person(name) {
 
}
 
Person.prototype = {
    name: 'kevin',
    getName: function () {
        console.log(this.name);
    }
};
 
var person1 = new Person();

可取:封装性好了一些

劣势:重写了原型,遗失了constructor属性

3.2 原型方式优化

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

1
2
3
4
5
6
7
8
9
10
11
12
13
function Person(name) {
 
}
 
Person.prototype = {
    constructor: Person,
    name: 'kevin',
    getName: function () {
        console.log(this.name);
    }
};
 
var person1 = new Person();

亮点:实例能够透过constructor属性找到所属构造函数

破绽:原型格局该有的破绽还是有

4. 结缘格局

构造函数形式与原型方式双剑合璧。

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

1
2
3
4
5
6
7
8
9
10
11
12
function Person(name) {
    this.name = name;
}
 
Person.prototype = {
    constructor: Person,
    getName: function () {
        console.log(this.name);
    }
};
 
var person1 = new Person();

优点:该共享的分享,该民用的私房,使用最多如牛毛的法门

缺欠:有的人便是愿意一切都写在一同,即更加好的封装性

4.1 动态原型方式

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

1
2
3
4
5
6
7
8
9
10
function Person(name) {
    this.name = name;
    if (typeof this.getName != "function") {
        Person.prototype.getName = function () {
            console.log(this.name);
        }
    }
}
 
var person1 = new Person();

只顾:使用动态原型格局时,无法用对象字面量重写原型

说明下为啥:

function Person(name) { this.name = name; if (typeof this.getName != "function") { Person.prototype = { constructor: Person, getName: function () { console.log(this.name); } } } } var person1 = new Person('kevin'); var person2 = new Person('daisy'); // 报错 并未该方法 person1.getName(); // 注释掉下边的代码,那句是足以实行的。 person2.getName();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Person(name) {
    this.name = name;
    if (typeof this.getName != "function") {
        Person.prototype = {
            constructor: Person,
            getName: function () {
                console.log(this.name);
            }
        }
    }
}
 
var person1 = new Person('kevin');
var person2 = new Person('daisy');
 
// 报错 并没有该方法
person1.getName();
 
// 注释掉上面的代码,这句是可以执行的。
person2.getName();

为掌握释那些标题,尽管起始进行var person1 = new Person('kevin')

万黄金年代对 new 和 apply 的尾部试行进度不是很纯熟,能够阅读尾部相关链接中的文章。

大家纪念下 new 的兑现步骤:

  1. 首先新建叁个指标
  2. 然后将指标的原型指向 Person.prototype
  3. 然后 Person.apply(obj)
  4. 归来这些目的

留意那时,回看下 apply 的贯彻步骤,会进行 obj.Person 方法,那时候就能施行 if 语句里的原委,注意构造函数的 prototype 属性指向了实例的原型,使用字面量格局一贯覆盖 Person.prototype,并不会改动实例的原型的值,person1 依旧是指向了早前的原型,并不是 Person.prototype。而在此之前的原型是平昔不 getName 方法的,所以就报错了!

黄金时代旦您不怕想用字面量格局写代码,能够品味下这种:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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

5.1 寄生构造函数方式

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

寄生构造函数情势,小编个人感到应当这么读:

寄生-构造函数-形式,也正是说寄生在构造函数的生机勃勃种办法。

也便是说打着构造函数的幌子浪得虚名,你看创设的实例使用 instanceof 都力所不及指向构造函数!

如此那般方法能够在优良境况下利用。比方大家想创建贰个享有额外措施的异样数组,但是又不想一向改正Array构造函数,大家可以这么写:

function SpecialArray() { var values = new Array(); for (var i = 0, len = arguments.length; i len; i ) { values.push(arguments[i]); } values.toPipedString = function () { return this.join("|"); }; return values; } var colors = new SpecialArray('red', 'blue', 'green'); var colors2 = SpecialArray('red2', 'blue2', 'green2'); console.log(colors); console.log(colors.toPipedString()); // red|blue|green console.log(colors2); console.log(colors2.toPipedString()); // red2|blue2|green2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function SpecialArray() {
    var values = new Array();
 
    for (var i = 0, len = arguments.length; i  len; i ) {
        values.push(arguments[i]);
    }
 
    values.toPipedString = function () {
        return this.join("|");
    };
    return values;
}
 
var colors = new SpecialArray('red', 'blue', 'green');
var colors2 = SpecialArray('red2', 'blue2', 'green2');
 
 
console.log(colors);
console.log(colors.toPipedString()); // red|blue|green
 
console.log(colors2);
console.log(colors2.toPipedString()); // red2|blue2|green2

您会发觉,其实所谓的寄生构造函数格局就是比工厂方式在创制对象的时候,多应用了叁个new,实际上两个的结果是均等的。

不过作者大概是指望能像使用普通 Array 一样采用 特略Array,即便把 SpecialArray 当成函数也如出豆蔻梢头辙能用,可是那并非作者的原意,也变得不美观。

在能够动用其它形式的场馆下,不要接受这种情势。

然则值得大器晚成提的是,上边例子中的循环:

for (var i = 0, len = arguments.length; i len; i ) { values.push(arguments[i]); }

1
2
3
for (var i = 0, len = arguments.length; i  len; i ) {
    values.push(arguments[i]);
}

能够替换成:

values.push.apply(values, arguments);

1
values.push.apply(values, arguments);

5.2 稳妥构造函数形式

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

所谓稳当对象,指的是从未国有属性,并且其艺术也不援用 this 的靶子。

与寄生构造函数形式有两点分化:

  1. 新创设的实例方法不引用 this
  2. 不应用 new 操作符调用构造函数

伏贴对象最契合在部分平安的条件中。

稳妥构造函数方式也跟工厂形式同样,十分的小概识别对象所属类型。

深远体系

JavaScript深切类别目录地址:。

JavaScript深刻连串推断写十六篇左右,目的在于帮我们捋顺JavaScript底层知识,重视讲明如原型、作用域、奉行上下文、变量对象、this、闭包、按值传递、call、apply、bind、new、世襲等难处概念。

举例有荒谬也许比超级大心的地点,请必得给与指正,相当多谢。借使喜欢或然具有启示,款待star,对小编也是风姿洒脱种驱策。

  1. JavaScirpt 深刻之从原型到原型链
  2. JavaScript 浓重之词法功用域和动态作用域
  3. JavaScript 深远之实施上下文栈
  4. JavaScript 深刻之变量对象
  5. JavaScript 深刻之效劳域链
  6. JavaScript 深切之从 ECMAScript 规范解读 this
  7. JavaScript 深远之奉行上下文
  8. JavaScript 深刻之闭包
  9. JavaScript 浓重之参数按值传递
  10. JavaScript 浓烈之call和apply的效仿完结
  11. JavaScript 深远之bind的效仿完毕
  12. JavaScript 浓郁之new的模拟达成
  13. JavaScript 长远之类数组对象与 arguments

    1 赞 收藏 评论

图片 1

本文由www.qjdy.com-奇迹赌场发布于佳美特设计,转载请注明出处:但是注意

关键词: JavaScript ag电子游戏大奖

上一篇:   译文出处

下一篇:没有了