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 相关文章推荐
setAttribute 与 class冲突解决
Feb 17 Javascript
javascript模仿msgbox提示效果代码
Jun 10 Javascript
javascript 动态添加事件代码
Nov 30 Javascript
jquery 图片轮换效果
Jul 29 Javascript
Javascript 类、命名空间、代码组织代码
Jul 31 Javascript
推荐10个超棒的jQuery工具提示插件
Oct 11 Javascript
js 实现数值的千分位及保存小数方法(推荐)
Aug 01 Javascript
深入理解JS实现快速排序和去重
Oct 17 Javascript
jQuery实现的表格前端排序功能示例
Sep 18 jQuery
在Vue中使用echarts的方法
Feb 05 Javascript
功能完善的小程序日历组件的实现
Mar 31 Javascript
JavaScript读取本地文件常用方法流程解析
Oct 12 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
使用adodb lite解决问题
2006/12/31 PHP
php利用事务处理转账问题
2015/04/22 PHP
php实现求相对时间函数
2015/06/15 PHP
javascript 流畅动画实现原理
2009/09/08 Javascript
将CKfinder整合进CKEditor3.0的新方法
2010/01/10 Javascript
Javascript Function对象扩展之延时执行函数
2010/07/06 Javascript
Nodejs实现批量下载妹纸图
2015/05/28 NodeJs
Underscore.js 1.3.3 中文注释翻译说明
2015/06/25 Javascript
遮罩层点击按钮弹出并且具有拖动和关闭效果(两种方法)
2015/08/20 Javascript
JS通过Cookie判断页面是否为首次打开
2016/02/05 Javascript
JQuery validate插件验证用户注册信息
2016/05/11 Javascript
详解Node.js模块间共享数据库连接的方法
2016/05/24 Javascript
jQuery制作圣诞主题页面 更像是爱情影集
2016/08/10 Javascript
ionic组件ion-tabs选项卡切换效果实例
2016/08/27 Javascript
4个顶级开源JavaScript图表库
2018/09/29 Javascript
移动端JS实现拖拽两种方法解析
2020/10/12 Javascript
Python Web框架Flask下网站开发入门实例
2015/02/08 Python
Python功能键的读取方法
2015/05/28 Python
Python实现图像几何变换
2015/07/06 Python
Python Django简单实现session登录注销过程详解
2019/08/06 Python
Python传递参数的多种方式(小结)
2019/09/18 Python
python3 使用Opencv打开USB摄像头,配置1080P分辨率的操作
2019/12/11 Python
Pandas实现一列数据分隔为两列
2020/05/18 Python
Python collections.deque双边队列原理详解
2020/10/05 Python
Django如何重置migration的几种情景
2021/02/24 Python
澳大利亚优质葡萄酒专家:Vintage Cellars
2019/01/08 全球购物
StudentUniverse英国:学生航班、酒店和旅游
2019/08/25 全球购物
英国时尚和家居用品零售商:Matalan
2021/02/28 全球购物
集团公司党的群众路线教育实践活动工作总结
2014/03/03 职场文书
警示教育活动总结
2014/05/05 职场文书
运动会口号大全
2014/06/07 职场文书
同志主要表现材料
2014/08/21 职场文书
公司副总经理岗位职责
2014/10/01 职场文书
银行优秀员工推荐信
2015/03/24 职场文书
解除劳动合同通知书范本
2015/04/16 职场文书
2015年统计员个人工作总结
2015/07/23 职场文书