热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

详细了解JavaScript中的构造器

构造函数跟普通函数非常相似,但是我们通过new关键字来使用它们。主要有两种类型的构造函数,native构造函数(Array,Object)它们可以在执行环境中自动生成,还有自定义的构造函数,你可以定义自己的方法和属性。

对构造函数有很好的理解是你掌握Javascript这门语言的重点。我们都知道Javascript不像其他语言,它没有class关键字,但是它有跟function非常相似的构造函数。这篇文章我们一起来详细地了解Javascript构造函数如何构造对象。

构造函数跟普通函数非常相似,但是我们通过new关键字来使用它们。主要有两种类型的构造函数,native构造函数(Array,Object)它们可以在执行环境中自动生成,还有自定义的构造函数,你可以定义自己的方法和属性。

当你想要创建很多相似的对象(拥有相同的属性和方法)的时候,使用构造函数是非常有效的。大部分程序员都遵循公约,使用大写字母开头来将构造函数和普通函数区分开。看看下面的代码。

function Book() { 
    // unfinished code
} 
var myBook = new Book();

最后一行代码创建了一个Book对象,并把它赋值给变量;这样完成之后,即使Book构造器没有做任何操作,myBook也是Book实例。正如你看到的,除了首字母大写和使用new关键字之外,构造函数和普通函数并没有什么区别。

判断实例的类型

判断某个对象是否为某种实例,我们可以使用instanceof操作符:

myBook instanceof Book    // => true
myBook instanceof String  // => false

注意:如果右边不是一个函数的实例,那么将会报错:

myBook instanceof {}; // => TypeError: invalid 'instanceof' operand ({})

另一种方法是使用constructor属性,所有对象实例都有一个constructor属性,这个属性指向创建它的构造函数。

myBook.cOnstructor== Book;   // => true

就像myBook的constructor指向Book一样。 所有对象都从它们的原型上继承了constructor这个属性:

var s = new String("text");
s.cOnstructor=== String;      // => true
"text".cOnstructor=== String; // => true
var o = new Object();
o.cOnstructor=== Object;      // => true
var o = {};
o.cOnstructor=== Object;      // => true
var a = new Array();
a.cOnstructor=== Array;       // => true
[].cOnstructor=== Array;      // => true

尽管使用constructor可以用来检测实例类型,但是建议还是使用instanceof方法。因为constructor属性是可以被重写的..用起来不太靠谱。

自定义构造函数

构造函数就像饼干印模。同一印模制作出来的,都是同一个diao样(男人没一个好东西也是这个道理)。

function Book(name, year) {
    this.name = name;
    this.year = '(' + year + ')';
}

Book构造器需要两个参数,当使用new关键字构造对象时,会把两个形参传给Book对象的name 和 year。

var firstBook = new Book("Pro AngularJS", 2014);
var secOndBook= new Book("Secrets Of The Javascript Ninja", 2013); 
var thirdBook = new Book("Javascript Patterns", 2010);

console.log(firstBook.name, firstBook.year);           
console.log(secondBook.name, secondBook.year);           
console.log(thirdBook.name, thirdBook.year);

Object.defineProperty 方法

Object.defineProperty 方法可以在构造器中被使用来配置属性。

function Book(name) { 
    Object.defineProperty(this, "name", { 
        get: function() { 
            return "Book: " + name;       
        },        
        set: function(newName) {            
            name = newName;        
        },               
        configurable: false     
    }); 
}
var myBook = new Book("Single Page Web Applications");
console.log(myBook.name);    // => Book: Single Page Web Applications
// we cannot delete the name property because "configurable" is set to false
delete myBook.name;    
console.log(myBook.name);    // => Book: Single Page Web Applications
// but we can change the value of the name property
myBook.name = "Testable Javascript";
console.log(myBook.name);    // => Book: Testable Javascript

上面的代码中是调用了祖先的方法。它提供了getter和setter接口。getter方法负责返回封装的值,setter方法接受参数,并把值赋给属性。当我们在某个属性上操作存取时,调用的就是这两个方法。通过配置configurable,我们可以设置该值能否被删除。

对象字面量表示法是首选的构造函数

Javascript语言九种内建的构造器:Object(), Array(), String(), Number(), Boolean(), Date(), Function(), Error() 以及 RegExp()。当我们需要创建这些值的时候,我们可以自由选择使用字面量或者构造器。但是相同情况下,字面量对象不仅易读,而且运行速度更快,因为他们可以在解析的时候被优化。所以当你需要使用简单对象的时候就使用字面量吧。

// a number object
// numbers have a toFixed() method
var obj = new Object(5);
obj.toFixed(2);     // => 5.00
// we can achieve the same result using literals
var num = 5;
num.toFixed(2);     // => 5.00
// a string object
// strings have a slice() method 
var obj = new String("text");
obj.slice(0,2);     // => "te"
// same as above
var string = "text";
string.slice(0,2);  // => "te"

使用new关键字是必不可少的

记得使用构造器的时候要用new关键字,如果你不小心忘记了,那么构造器中的this指向的是global对象(浏览器中默认为window)。

function Book(name, year) {
    console.log(this);
    this.name = name;
    this.year = year;
}
var myBook = Book("js book", 2014);  
console.log(myBook instanceof Book);  
console.log(window.name, window.year);
var myBook = new Book("js book", 2014);  
console.log(myBook instanceof Book);  
console.log(myBook.name, myBook.year);

上面的代码运行结果如下所示:

如果是在严格模式下,上面的代码将会抛出错误,因为严格模式不允许我们不使用new关键字调用构造器。

适用范围更高的构造器

为了解决可能会忘记使用new关键字的风险,我们可以通过判断this的值创建适用范围更高的构造器。

function Book(name) { 
    if (!(this instanceof Book)) { 
        // the constructor was called without "new".
        return new Book(name);
    } 
}

加上这段代码之后,我们就可以‘肆无忌惮’地使用构造器了。

function Book(name, year) { 
    if (!(this instanceof Book)) { 
        return new Book(name, year);
    }
    this.name = name;
    this.year = year;
}
var person1 = new Book("js book", 2014);
var person2 = Book("js book", 2014);
console.log(person1 instanceof Book);    // => true
console.log(person2 instanceof Book);    // => true

很多内建的构造器都是这么做的。通过判断this是否为当前类型。如果程序员忘记加new关键字,那么我们就返回一个通过new出来的对象。

结论

Javascript没有类这种说法(但是它可以使面向对象的),所以对于习惯了使用类的程序员来说是种困惑。当然Javascript的构造函数跟普通函数没什么区别,只是通过new关键字生成出来而已。如果我们需要”印饼干”的话,它就非常有用了。

推荐教程:《Javascript视频教程》

以上就是详细了解Javascript中的构造器的详细内容,更多请关注 第一PHP社区 其它相关文章!


推荐阅读
  • 利用无代码平台实现高效业务应用开发
    随着市场环境的变化加速,全球企业都在探索更为敏捷的应用开发模式,以便快速响应新兴的商业机遇。然而,传统的软件开发方式不仅成本高昂,而且耗时较长,这往往导致IT与业务部门之间的合作障碍,进而影响项目的成功。本文将探讨如何通过无代码开发平台解决这些问题。 ... [详细]
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
  • 本文探讨了程序员这一职业的本质,认为他们是专注于问题解决的专业人士。文章深入分析了他们的日常工作状态、个人品质以及面对挑战时的态度,强调了编程不仅是一项技术活动,更是个人成长和精神修炼的过程。 ... [详细]
  • 我的读书清单(持续更新)201705311.《一千零一夜》2006(四五年级)2.《中华上下五千年》2008(初一)3.《鲁滨孙漂流记》2008(初二)4.《钢铁是怎样炼成的》20 ... [详细]
  • Python 领跑!2019年2月编程语言排名更新
    根据最新的编程语言流行指数(PYPL)排行榜,Python 在2019年2月的份额达到了26.42%,稳坐榜首位置。 ... [详细]
  • 汇编语言:编程世界的始祖,连C语言都敬畏三分!
    当C语言还在萌芽阶段时,它首次接触到了汇编语言,并对其简洁性感到震惊。尽管汇编语言的指令极其简单,但它却是所有现代编程语言的基础,其重要性不言而喻。 ... [详细]
  • 探索OpenWrt中的LuCI框架
    本文深入探讨了OpenWrt系统中轻量级HTTP服务器uhttpd的工作原理及其配置,重点介绍了LuCI界面的实现机制。 ... [详细]
  • 本问题探讨了如何从给定的一个不含任何长度为2或以上的回文子串的字符串中,找到下一个同样不含此类回文子串的字典序字符串。字符串中的字符限定在英文前N个字母内。 ... [详细]
  • Python Selenium WebDriver 浏览器驱动详解与实践
    本文详细介绍了如何使用Python结合Selenium和unittest构建自动化测试框架,重点解析了WebDriver浏览器驱动的配置与使用方法,涵盖Chrome、Firefox、IE/Edge等主流浏览器。 ... [详细]
  • 客厅布置指南:如何优化财位布局
    了解如何通过合理布置客厅来提升家居风水,特别是财位的优化技巧。 ... [详细]
  • 探讨如何在给定数组中寻找一个连续子数组,使其和至少达到指定值s,同时确保子数组长度最短。 ... [详细]
  • IntelliJ IDEA配置微服务启动显示
    通过编辑IntelliJ IDEA的workspace.xml文件,可以实现微服务启动对象的显示。具体步骤包括定位并修改workspace.xml中的RunDashboard部分。 ... [详细]
  • 随着技术的发展,Python因其高效性和灵活性,在多个领域得到了广泛应用,特别是在大数据处理和网络爬虫开发方面。本文将探讨学习Python是否能够胜任大数据和网络爬虫工程师的工作,并分析其职业前景。 ... [详细]
  • QQ推出新功能:个性化QID身份卡
    您是否还记得曾经风靡一时的即时通讯工具QQ?近日,QQ悄然上线了一项新功能——QID身份卡。这项功能将如何改变用户的社交体验?本文为您详细解读。 ... [详细]
  • protobuf 使用心得:解析与编码陷阱
    本文记录了一次在广告系统中使用protobuf进行数据交换时遇到的问题及其解决过程。通过这次经历,我们将探讨protobuf的特性和编码机制,帮助开发者避免类似的陷阱。 ... [详细]
author-avatar
莫忠健
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有