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 获取class的元素的方法 以及创建方法getElementsByClassName
Mar 11 Javascript
javascript中怎么做对象的类型判断
Nov 11 Javascript
jquery ajax应用中iframe自适应高度问题解决方法
Apr 12 Javascript
加载列表时jquery获取ul中第一个li的属性
Nov 02 Javascript
jQuery控制frames及frame页面JS的方法
Mar 08 Javascript
javascript输出AscII码扩展集中的字符方法
Dec 26 Javascript
jQuery实现手机上输入后隐藏键盘功能
Jan 04 Javascript
vue实现简单表格组件实例详解
Apr 16 Javascript
Vue2.2.0+新特性整理及注意事项
Aug 22 Javascript
nuxt配置通过指定IP和端口访问的实现
Jan 08 Javascript
Vue中Object.assign清空数据报错的解决方案
Mar 03 Vue.js
React更新渲染原理深入分析
Dec 24 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为表单获取的URL 地址预设 http 字符串函数代码
2010/05/26 PHP
Drupal7连接多个数据库及常见问题解决
2014/03/02 PHP
asp.net下使用jquery 的ajax+WebService+json 实现无刷新取后台值的实现代码
2010/09/19 Javascript
jQueryUI如何自定义组件实现代码
2010/11/14 Javascript
Array.prototype.concat不是通用方法反驳[译]
2012/09/20 Javascript
ajax中get和post的说明及使用与区别
2012/12/23 Javascript
如何解决ligerUI布局时Center中的Tab高度大小
2015/11/24 Javascript
使用jQuery实现Web页面换肤功能的要点解析
2016/05/12 Javascript
JavaScript6 let 新语法优势介绍
2016/07/15 Javascript
浅谈Javascript数据属性与访问器属性
2016/07/26 Javascript
Nodejs连接mysql并实现增、删、改、查操作的方法详解
2018/01/04 NodeJs
20行JS代码实现粘贴板复制功能
2018/02/06 Javascript
nodejs简单读写excel内容的方法示例
2018/03/16 NodeJs
javascript、php关键字搜索函数的使用方法
2018/05/29 Javascript
微信打开网址添加在浏览器中打开提示的办法
2019/05/20 Javascript
koa router 多文件引入的方法示例
2019/05/22 Javascript
如何对react hooks进行单元测试的方法
2019/08/14 Javascript
vue中注册自定义的全局js方法
2019/11/15 Javascript
autojs 蚂蚁森林能量自动拾取即给指定好友浇水的实现方法
2020/05/03 Javascript
[00:20]DOTA2荣耀之路7:-ah fu-抢盾
2018/05/31 DOTA
python在windows下实现ping操作并接收返回信息的方法
2015/03/20 Python
Python标准库06之子进程 (subprocess包) 详解
2016/12/07 Python
Python发送手机动态验证码代码实例
2020/02/28 Python
Python 线性回归分析以及评价指标详解
2020/04/02 Python
Python 求向量的余弦值操作
2021/03/04 Python
IE9对HTML5中部分属性不支持的原因分析
2014/10/15 HTML / CSS
澳大利亚当地社区首选的光学商店:1001 Optical
2019/08/24 全球购物
Bluebella德国官网:英国性感内衣和睡衣品牌
2019/11/08 全球购物
教师年度考核自我鉴定
2014/01/19 职场文书
新员工试用期自我鉴定
2014/04/17 职场文书
文明班级建设方案
2014/05/15 职场文书
我们的节日端午节活动总结
2015/02/11 职场文书
会议通知范文
2015/04/15 职场文书
AJAX学习笔记
2021/05/18 Javascript
Centos系统通过Docker安装并搭建MongoDB数据库
2022/04/12 MongoDB
清空 Oracle 安装记录并重新安装
2022/04/26 Oracle