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 相关文章推荐
js操作ajax返回的json的注意问题!
Feb 23 Javascript
jQuery MD5加密实现代码
Mar 15 Javascript
jcrop基本参数一览
Jul 16 Javascript
js实现图片拖动改变顺序附图
May 13 Javascript
手机端 HTML5使用photoswipe.js仿微信朋友圈图片放大效果
Aug 25 Javascript
jQuery用FormData实现文件上传的方法
Nov 21 Javascript
JavaScript设计模式之策略模式详解
Jun 09 Javascript
Angularjs单选框相关的示例代码
Aug 17 Javascript
解析vue中的$mount
Dec 21 Javascript
webpack打包node.js后端项目的方法
Mar 10 Javascript
js实现头像上传并且可预览提交
Dec 25 Javascript
Vue OpenLayer测距功能的实现
Apr 20 Vue.js
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
Zend引擎的发展 [15]
2006/10/09 PHP
PHP高自定义性安全验证码代码
2011/11/27 PHP
php urlencode()与urldecode()函数字符编码原理详解
2011/12/06 PHP
简单的方法让你的后台登录更加安全(php中加session验证)
2012/08/22 PHP
基于GD2图形库的PHP生成图片缩略图类代码分享
2015/02/08 PHP
php+ajax实现无刷新动态加载数据技术
2015/04/28 PHP
IOS 开发之NSDictionary转换成JSON字符串
2017/08/14 PHP
网页和浏览器兼容性问题汇总(draft1)
2009/06/01 Javascript
键盘KeyCode值列表汇总
2013/11/26 Javascript
对js关键字命名的疑问介绍
2014/04/25 Javascript
浅析webapp框架AngularUI的demo
2014/12/21 Javascript
非常实用的12个jquery代码片段
2015/11/02 Javascript
微信小程序 富文本转文本实例详解
2016/10/24 Javascript
使用Bootrap和Vue实现仿百度搜索功能
2017/10/26 Javascript
详解angular脏检查原理及伪代码实现
2018/06/08 Javascript
JavaScript实现的鼠标跟随特效示例【2则实例】
2018/12/22 Javascript
用Electron写个带界面的nodejs爬虫的实现方法
2019/01/29 NodeJs
使用Karma做vue组件单元测试的实现
2020/01/16 Javascript
详解Vue数据驱动原理
2020/11/17 Javascript
[01:00:12]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第一场
2018/04/09 DOTA
python中使用urllib2获取http请求状态码的代码例子
2014/07/07 Python
Django小白教程之Django用户注册与登录
2016/04/22 Python
Python实现Linux的find命令实例分享
2017/06/04 Python
Python使用pyautogui模块实现自动化鼠标和键盘操作示例
2018/09/04 Python
Python拼接字符串的7种方法总结
2018/11/01 Python
简单了解python反射机制的一些知识
2019/07/13 Python
django如何实现视图重定向
2019/07/24 Python
python3 sleep 延时秒 毫秒实例
2020/05/04 Python
俄罗斯茶和咖啡网上商店:Tea.ru
2021/01/26 全球购物
七年级地理教学反思
2014/01/26 职场文书
中学生期中自我鉴定
2014/04/20 职场文书
护士工作失误检讨书
2014/09/14 职场文书
学习优秀共产党员先进事迹思想报告
2014/09/17 职场文书
欢迎新生标语
2014/10/06 职场文书
世界十大儿童漫画书排名,法国国宝漫画排第五,第二是轰动日本连环
2022/03/18 欧美动漫
Docker官方工具docker-registry案例演示
2022/04/13 Servers