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 相关文章推荐
asp javascript 实现关闭窗口时保存数据的办法
Nov 24 Javascript
简单的js分页脚本
May 21 Javascript
jQuery点击后一组图片左右滑动的实现代码
Aug 16 Javascript
21个值得收藏的Javascript技巧
Feb 04 Javascript
ListBox实现上移,下移,左移,右移的简单实例
Feb 13 Javascript
node.js中的fs.chmodSync方法使用说明
Dec 18 Javascript
js数组去重的方法汇总
Jul 29 Javascript
Extjs gridpanel 中的checkbox(复选框)根据某行的条件不能选中的解决方法
Feb 17 Javascript
json的结构与遍历方法实例分析
Apr 25 Javascript
AngularJS实现单一页面内设置跳转路由的方法
Jun 28 Javascript
vue.js使用v-model指令实现的数据双向绑定功能示例
May 22 Javascript
Vue移动端项目实现使用手机预览调试操作
Jul 18 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
简单采集了yahoo的一些数据
2007/02/14 PHP
延长phpmyadmin登录时间的方法
2011/02/06 PHP
php根据isbn书号查询amazon网站上的图书信息的示例
2014/02/13 PHP
php中__destruct与register_shutdown_function执行的先后顺序问题
2014/10/17 PHP
php使用PDO操作MySQL数据库实例
2014/12/30 PHP
Laravel 5 框架入门(二)构建 Pages 的管理功能
2015/04/09 PHP
LaravelS通过Swoole加速Laravel/Lumen详解
2018/03/02 PHP
原生Js与jquery的多组处理, 仅展开一个区块的折叠效果
2011/01/09 Javascript
js 获取屏幕各种宽高的方法(浏览器兼容)
2013/05/15 Javascript
jquery使用animate方法实现控制元素移动
2015/03/27 Javascript
JavaScript中switch语句的用法详解
2015/06/03 Javascript
AngularJS 使用$sce控制代码安全检查
2016/01/05 Javascript
js实现弹窗居中的简单实例
2016/10/09 Javascript
使用BootStrap实现悬浮窗口的效果
2016/12/13 Javascript
浅谈 vue 中的 watcher
2017/12/04 Javascript
element ui里dialog关闭后清除验证条件方法
2018/02/26 Javascript
Layui选项卡制作历史浏览记录的方法
2019/09/28 Javascript
vue制作toast组件npm包示例代码
2020/10/29 Javascript
python实现的AES双向对称加密解密与用法分析
2017/05/02 Python
python爬虫入门教程--优雅的HTTP库requests(二)
2017/05/25 Python
Python实现求数列和的方法示例
2018/01/12 Python
Python推导式简单示例【列表推导式、字典推导式与集合推导式】
2018/12/04 Python
Python 支付整合开发包的实现
2019/01/23 Python
python 实现波浪滤镜特效
2020/12/02 Python
详解python日志输出使用配置文件格式
2021/02/10 Python
html5实现的便签特效(实战分享)
2013/11/29 HTML / CSS
英国建筑用品在线:Building Supplies Online(BSO)
2018/04/30 全球购物
企业演讲稿范文
2013/12/28 职场文书
个人评价范文分享
2014/01/11 职场文书
大学英语演讲稿范文
2014/04/24 职场文书
中学生旷课检讨书模板
2014/10/08 职场文书
2014矛盾纠纷排查调处工作总结
2014/12/09 职场文书
优秀党支部申报材料
2014/12/24 职场文书
秦始皇兵马俑导游词
2015/02/02 职场文书
Springboot配置suffix指定mvc视图的后缀方法
2021/07/03 Java/Android
golang 语言中错误处理机制
2021/08/30 Golang