资讯专栏INFORMATION COLUMN

第三期:基于红皮书「创建js对象的6种方法」再讨论(1)

liaoyg8023 / 1381人阅读

摘要:构造函数里的作用在的时候,所谓的作用域赋给新对象,就是使用了方法。如果我们不用,也可以实现指向我们想指向的对象构造函数当做普通函数使用,构造函数当做普通函数使用,这些变式其实都是在充分了解和的用法后,自然写出来的。

这一期所书写的目的并不是为了介绍创建对象的方法,在红皮书里面,例子其实很清楚。在这篇文章中,想讨论一下书中细节,并没有解释太清楚的地方。

工厂模式
//工厂模式书本「
function createPerson(name,age){
    var obj=new Object();
    obj.name=name;
    obj.age=age;
    obj.load=function(){
        console.log(obj.name,obj.age);
    }
    return obj;
}

var toti=createPerson("toti",18);
toti.load();
//」工厂模式书本

工厂模式的一些要点:

解决:

创建多个相似对象问题

传参

缺点:不能识别对象类型

优化:一般使用对象字面量写法,再返回

思考

对象暴露出来,其实也可以用,但是赋值需要重复。

包在一个函数里面,传参方便

这个模式做了什么?

创建一个Object实例对象

为实例obj添加属性、方法

返回实例obj

相当于使用了一个普通的函数,去让这个对象可以复用。

书中:「不能识别对象类型」如何理解?

我们的实例,当我们去console.log(toti)的时候。但是工厂模式下,

我们去获取这个实例的时候,只能简单的判断它是一个对象。这就是它一个缺点,于是我们有了后面的构造函数模式

使用对象字面量写法优化

//工厂模式对象字面量「
function createPerson(name,age){
    var obj={
        name:name,
        age:age,
        load:function(){
            console.log(this.name,this.age);
        }
    }
    return obj;
}

var mary=createPerson("mary",18);
mary.load();
//」工厂模式对象字面量

对象字面量注意问题

this的用法

在obj对象里面,this.name&this.age指向obj的作用域的name&age

如果不使用this,则name和age,指向createPerson的作用域。

在本例中,使用this.name,name都可以,因为是传参,所以createPerson和obj两个作用域变量一样

构造函数模式
//「 构造函数模式;「 构造函数当做构造函数使用,用new
function Person(name,age){
    this.name=name;
    this.age=age;
    this.load=function(){
        console.log(this.name,this.age);
    }
}

var toti=new Person("toti",18);
toti.load();
console.log(typeof toti);
// 」构造函数模式;」构造函数当做构造函数使用,用new

发生了什么?

在解释发生的事情前,我们要先详细了解下new的作用。在红皮书中,new的作用,解释的的确很浅,简单几行字,不细读,很难理清其中的逻辑。

NEW的作用

红皮书中是这样解释的:

创建一个新对象

将构造函数的作用域赋值给新对象

执行构造函数中的代码

返回新对象

这几行文字,一开始我也以为我读懂了,但是它实在没有很好地给读者说明白new到底怎么用的。

在这里,我引用一个我提问中的网友的回答,下面是来自wei0613的回答:

function CO(){
    this.p = “I’m in constructed object”;
    this.alertP = function(){
        alert(this.p);
    }
}
var o2 = new CO();
var obj  ={};
obj.__proto__ = CO.prototype;
CO.call(obj);
return obj;

他用代码形式给我们讲解了其中发生了什么事:

new先创建了一个对象obj

然后CO函数的原型赋值给对象obj的原型

CO函数再使用call/apply方法把作用域赋给obj

到这一步才执行构造函数Co里面的代码!!!

返回obj对象

大家可能第一眼,并不能发现我这里的逻辑和红皮书的逻辑有什么区别。首先,红皮书的逻辑中,很明显少了原型创建发生在哪一步,如果这里不清楚,会影响大家理解接下来原型模式和动态原型模式的理解;其次,第4步是最重要的,也就是构造函数的代码执行,是发生在第4步,call的使用和原型链的形成都发生在之前。如果我们仅仅只有一个大概概念,当我们遇到对象字面量重写的时候,我们很可能发现我们代码写得都没有问题,但是就是出bug的情况。这个工作流逻辑大家一定要清楚。

构造函数里this的作用

在new的时候,所谓的作用域赋给新对象,就是使用了call/apply方法。

Person.apply(obj,arguments);

this就指向了obj对象

把this的属性方法一个个添加到obj对象里面

其他不是this的属性和方法,都会被忽略,比如:

function Person(name, age,job){
    this.name=name;
    this.age=age;
    this.load=function(){
        console.log(this.name,this.age);
    }
    var job=job;
}

job就不会被写入obj对象里面

注意,当我们new Person()的时候,是把函数当作构造函数使用的,但是它也是函数,可以像普通函数一样使用

//「 构造函数当做普通函数使用,不用new
function Person(name,age){
    this.name=name;
    this.age=age;
    this.load=function(){
        console.log(this.name,this.age);
    }
}

var mike=Person("mike",18);
//mike.load();会报错,Person没有对象返回
window.load();
// 」构造函数当做普通函数使用,不用new

直接使用函数,等于在当前作用域下运行。在这种情况下,我们则会把this指向这个环境的作用域,在这里是window。我们使用mike.load()会报错,因为属性和方法并没有添加到mike这个对象中,而是添加到了window这个对象。

如果我们不用new,也可以实现this指向我们想指向的对象

//「 构造函数当做普通函数使用,call,apply
function Person(name,age){
    this.name=name;
    this.age=age;
    this.load=function(){
        console.log(this.name,this.age);
    }
}

var obj={};
Person.call(obj,"mike",18);
obj.load();
// 」构造函数当做普通函数使用,call,apply

这些变式其实都是在充分了解new和this的用法后,自然写出来的。通过些变式,大家可以更好理解它们的用法。

相比工厂模式,构造函数模式的优缺点及思考

当我们console.log(toti):

我们回顾工厂模式下,是:

所以构造函数模式在这里比工厂模式更好,看到这里大家应该明白书中:「不能识别对象类型」的问题了。

构造函数模式要点

解决:可以识别为一种特定的类型

缺点:构造函数的每个方法都被实例了一遍

思考:

构造函数开头大写,其他函数开头小写

不使用new,相当于普通函数使用,this指向window,为window添加变量和方法

也可以使用call和apply来为第三方作用域添加

重点:

new

this

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/82317.html

相关文章

  • 等风来!区块链熊市,技术人就要做技术投资

    摘要:年的区块链牛市已经过去了,目前看来,年会是一个大熊市,投资抄币估计也捞不着什么。熊市囤技术,其实是技术人员很好的选择。三期同学讨论积累资料的地址等风来区块链熊市,技术人就要做技术投资。 2017 年的区块链牛市已经过去了,目前看来,2018 年会是一个大熊市,投资抄币估计也捞不着什么。熊市只能囤囤币,囤囤技术,只能等下一轮风起了。熊市囤技术,其实是技术人员很好的选择。等区块链牛市来了,...

    番茄西红柿 评论0 收藏0
  • 【翻译】理解 IPFS 白皮书 1部分

    摘要:理解白皮书第部分原文链接哦不,白皮书加密货币区块链世界喜爱白皮书,也不例外。要理解的工作原理,最好一步一步地学习白皮书。从开始,白皮书中明确提到了三个实现。白皮书指出小值等于或小于直接存储在上。 理解 IPFS 白皮书 第 1 部分 原文链接:https://decentralized.blog/un... 哦不,白皮书! 加密货币 / 区块链世界喜爱白皮书,IPFS 也不例外。 它起...

    Ilikewhite 评论0 收藏0
  • 每周前端开源推荐三期

    摘要:每周前端开源推荐第三期是一个用很炫的动画来展示数字的库,效果非常赞。把放在第一位是因为现在毫无疑问是最流行的实时框架。如此巨额的投资保证了开源小组高质的开发,目前版本号是。目前貌似主要面向请应用。 每周前端开源推荐第三期 HubSpot / odometer Beautiful CSS3 Number Transitions #hubspot-open-source h...

    littleGrow 评论0 收藏0
  • 每周前端开源推荐三期

    摘要:每周前端开源推荐第三期是一个用很炫的动画来展示数字的库,效果非常赞。把放在第一位是因为现在毫无疑问是最流行的实时框架。如此巨额的投资保证了开源小组高质的开发,目前版本号是。目前貌似主要面向请应用。 每周前端开源推荐第三期 HubSpot / odometer Beautiful CSS3 Number Transitions #hubspot-open-source h...

    senntyou 评论0 收藏0
  • 每周前端开源推荐三期

    摘要:每周前端开源推荐第三期是一个用很炫的动画来展示数字的库,效果非常赞。把放在第一位是因为现在毫无疑问是最流行的实时框架。如此巨额的投资保证了开源小组高质的开发,目前版本号是。目前貌似主要面向请应用。 每周前端开源推荐第三期 HubSpot / odometer Beautiful CSS3 Number Transitions #hubspot-open-source h...

    enrecul101 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<