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 相关文章推荐
解javascript 混淆加密收藏
Jan 16 Javascript
jquery 学习笔记 传智博客佟老师附详细注释
Sep 12 Javascript
基于Jquery的温度计动画效果
Jun 18 Javascript
JS实现一键回顶功能示例代码
Oct 28 Javascript
Javascript判断图片尺寸大小实例分析
Jun 16 Javascript
基于javascript实现简单计算器功能
Jan 03 Javascript
在ASP.NET MVC项目中使用RequireJS库的用法示例
Feb 15 Javascript
jQuery判断元素是否显示 是否隐藏的简单实现代码
May 19 Javascript
关于Iframe父页面与子页面之间的相互调用
Nov 22 Javascript
angular4中引入echarts的方法示例
Jan 29 Javascript
js的新生代垃圾回收知识点总结
Aug 22 Javascript
JS数组属性去重并校验重复数据
Jan 10 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截取后台登陆密码的代码
2012/05/05 PHP
php随机取mysql记录方法小结
2014/12/27 PHP
php接口隔离原则实例分析
2019/11/11 PHP
sina的lightbox效果。
2007/01/09 Javascript
Jquery中getJSON在asp.net中的使用说明
2011/03/10 Javascript
js+css实现增加表单可用性之提示文字
2013/06/03 Javascript
jquery Ajax 实现加载数据前动画效果的示例代码
2014/02/07 Javascript
jQuery Ajax 加载数据时异步显示加载动画
2016/08/01 Javascript
jquery 属性选择器(匹配具有指定属性的元素)
2016/09/06 Javascript
利用JS判断鼠标移入元素的方向
2016/12/11 Javascript
js实现彩色条纹滚动条效果
2017/03/15 Javascript
JavaScript 函数的定义-调用、注意事项
2017/04/16 Javascript
一个简单的node.js界面实现方法
2018/06/01 Javascript
Vue中 v-if 和v-else-if页面加载出现闪现的问题及解决方法
2018/10/12 Javascript
vue实现随机验证码功能的实例代码
2019/04/30 Javascript
Node.js 深度调试方法解析
2020/07/28 Javascript
详解Python3中的Sequence type的使用
2015/08/01 Python
详谈pandas中agg函数和apply函数的区别
2018/04/20 Python
python字符串循环左移
2019/03/08 Python
python实现在函数中修改变量值的方法
2019/07/16 Python
pywinauto自动化操作记事本
2019/08/26 Python
python实现udp聊天窗口
2020/03/31 Python
Python把图片转化为pdf代码实例
2020/07/28 Python
Python 保存加载mat格式文件的示例代码
2020/08/04 Python
关于PySnooper 永远不要使用print进行调试的问题
2021/03/04 Python
LTD Commodities:礼品,独特发现,家居装饰,家用器皿
2017/08/11 全球购物
接口可以包含哪些成员
2012/09/30 面试题
Windows和Linux动态库应用异同
2016/04/17 面试题
临床医学大学生求职信
2013/09/28 职场文书
生物科学系大学生的自我评价
2013/12/20 职场文书
庆祝国庆节演讲稿2014
2014/09/19 职场文书
2014学校领导四风对照检查材料思想汇报
2014/09/23 职场文书
2015年体育教师个人工作总结
2015/05/12 职场文书
致三级跳运动员加油稿
2015/07/21 职场文书
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
2022/02/12 Redis
Nginx配置根据url参数重定向
2022/04/11 Servers