Javascript学习笔记之函数篇(五) : 构造函数


Posted in Javascript onNovember 23, 2014

Javascript 中的构造函数与其他语言相比也是不同的。任何通过关键字 new 调用的函数都可以当做构造函数。
在构造函数体内,this 指向新创建的对象。如果构造函数体内没有显示的 return 表达式,那么我们就默认返回 this,也就是新建的对象。

function Foo() {

    this.bla = 1;

}

Foo.prototype.test = function() {

    console.log(this.bla);

};

var test = new Foo();

上面的代码将 Foo 作为构造函数进行调用,并将新建对象的原型(__proto__)指向了 Foo.prototype。
如果我们在构造函数内定义返回的 return 表达式,构造函数就会返回整个表达式,但这个返回表达式必须为一个对象。

function Bar() {

    return 2;

}

new Bar(); // a new object

function Test() {

    this.value = 2;

    return {

        foo: 1

    };

}

new Test(); // the returned object

如果 new 被省略,那么函数将不能返回一个新的对象。

function Foo() {

    this.bla = 1; // gets set on the global object

}

Foo(); // undefined

上面的例子可能在某些场景下也可以运行,但由于 Javascript 中 this 的工作机制,这里 this 将指向全局对象。

工厂模式

为了能够不使用关键字 new,构造函数将不得不显示返回一个值。

function Bar() {

    var value = 1;

    return {

        method: function() {

            return value;

        }

    }

}

Bar.prototype = {

    foo: function() {}

};

new Bar();

Bar();

上例中使不使用 new 来调用函数 Bar 达到的效果是一样的,将会返回一个新建的包含 method 方法的对象,这里实际上就是一个闭包。
这里需要注意一点,new Bar() 将不会返回 Bar.prototype,而是在 return 表达式内函数 method 的原型对象。
上例中,使用 new 与否在功能上是无差异的。

通过工厂模式创建新的对象

我们经常被提醒不要使用 new,因为一旦忘记了它的使用将导致错误。
为了创建一个对象,我们更愿意使用工厂模式并在工厂模式内构造一个新的对象。

function Foo() {

    var obj = {};

    obj.value = 'blub';
    var private = 2;

    obj.someMethod = function(value) {

        this.value = value;

    }
    obj.getPrivate = function() {

        return private;

    }

    return obj;

}

尽管上例代码比使用 new 时更不容易出错,而且在使用私有变量时将更加方便,但同时也有一些不好的地方:

因为不能共享原型对象,所以需要更多的内存。
为了实现继承,工厂模式需要拷贝另一个对象的所有方法或者将其作为新对象的原型。
放弃原型链只是为了避免使用 new,这似乎与 Javascript 语言的精神相悖。

总结

尽管使用 new 可能比较容易产生错误,但这并不能成为放弃使用原型链的原因。至于最后采取哪种方式,这需要根据应用的需求而定。最好的方式就是选择一种风格并坚持下去。

简单的说构造函数就是初始化一个实例对象,对象的prototype属性是继承一个实例对象。

Javascript 相关文章推荐
图片按比例缩放函数
Jun 26 Javascript
超级退弹代码
Jul 07 Javascript
javascript中的缓动效果实现程序
Dec 29 Javascript
利用javaScript实现点击输入框弹出窗体选择信息
Dec 11 Javascript
JavaScript简单获取系统当前时间完整示例
Aug 02 Javascript
JS实现表单验证功能(验证手机号是否存在,验证码倒计时)
Oct 11 Javascript
移动web开发之touch事件实例详解
Jan 17 Javascript
关于vue面试题汇总
Mar 20 Javascript
JavaScript判断浏览器运行环境的详细方法
Jun 30 Javascript
node.js使用fs读取文件出错的解决方案
Oct 23 Javascript
vue 根据选择条件显示指定参数的例子
Nov 09 Javascript
使用Canvas绘制一个游戏人物属性图
Mar 25 Javascript
Javascript学习笔记之函数篇(四):arguments 对象
Nov 23 #Javascript
Javascript学习笔记之 函数篇(三) : 闭包和引用
Nov 23 #Javascript
js实例属性和原型属性示例详解
Nov 23 #Javascript
JS常用函数使用指南
Nov 23 #Javascript
浅谈JSON和JSONP区别及jQuery的ajax jsonp的使用
Nov 23 #Javascript
理解jQuery stop()方法
Nov 21 #Javascript
JS中三目运算符和if else的区别分析与示例
Nov 21 #Javascript
You might like
PHP音乐采集(部分代码)
2007/02/14 PHP
php file_get_contents函数轻松采集html数据
2010/04/22 PHP
php小偷相关截取函数备忘
2010/11/28 PHP
PHP curl使用实例
2015/07/02 PHP
PHP批量去除BOM头内容信息代码
2016/03/11 PHP
php版微信公众平台之微信网页登陆授权示例
2016/09/23 PHP
PHP生成随机数的方法总结
2018/03/01 PHP
CL vs ForZe BO5 第二场 2.13
2021/03/10 DOTA
javascript一点特殊用法
2008/05/28 Javascript
escape编码与unescape解码汉字出现乱码的解决方法
2014/07/02 Javascript
javascript设计模式之Adapter模式【适配器模式】实现方法示例
2017/01/13 Javascript
微信小程序template模板实例详解
2017/10/27 Javascript
Vue使用Canvas绘制图片、矩形、线条、文字,下载图片
2019/04/26 Javascript
Vue项目实现换肤功能的一种方案分析
2019/08/28 Javascript
vue 获取元素额外生成的data-v-xxx操作
2020/09/09 Javascript
图解JS原型和原型链实现原理
2020/09/15 Javascript
JS如何实现在弹出窗口中加载页面
2020/12/03 Javascript
[01:39](回顾)各路豪强针锋相对,几经鏖战四强产生
2014/07/01 DOTA
python实现带错误处理功能的远程文件读取方法
2015/04/29 Python
python登录pop3邮件服务器接收邮件的方法
2015/04/30 Python
Scrapy使用的基本流程与实例讲解
2018/10/21 Python
详解安装mitmproxy以及遇到的坑和简单用法
2019/01/21 Python
Python应用领域和就业形势分析总结
2019/05/14 Python
Python logging设置和logger解析
2019/08/28 Python
Python使用qrcode二维码库生成二维码方法详解
2020/02/17 Python
菲律宾购物网站:Lazada菲律宾
2018/04/05 全球购物
岗位职责定义及内容
2013/11/08 职场文书
护士求职推荐信范文
2013/11/23 职场文书
会计学个人自荐信模板
2013/12/13 职场文书
医学生自我评价
2014/01/27 职场文书
中学教师教育感言
2014/02/21 职场文书
捐助倡议书范文
2014/04/15 职场文书
三方协议书范本
2014/04/22 职场文书
教导主任竞聘演讲稿
2014/05/16 职场文书
初中开学典礼新闻稿
2015/07/17 职场文书
校运会通讯稿
2015/07/18 职场文书