JavaScript支持以字面声名法(Literal)的方式来声名对象和数组,相对于构造函数(constructor)的方式,Literal的声 名方式更简洁,更易读,也更少导致Bug。事实上,JSON就是用Literal的方式定义的JavaScript数据格式。

1. 用Literal的方式创建对象
JavaScript里的对象大概就好像是一个装着一堆“键-值对”的哈希表。下面我们给出以Literal方式声名对象的语法:

  • 用花括号把对象的内部包起来(即{});
  • 对象中的各个键值对之间要用逗号分开;
  • 键与值之间用冒号分开;
  • 当你把这个对象赋值给一个变量,别忘记在后面的花括号}那里标识赋值语句的结束(即加分号';')。

对于”值“来说,有可能是简单的数据类型,也可能是其它的对象,还可以是方法。通过Literal的方式创建出来的对象,其内容可以随时修改。比如:

  1. // start with an empty object
  2. var dog = {};
  3.  
  4. // add one property
  5. dog.name = "Benji";
  6.  
  7. // now add a method
  8. dog.getName = function () {
  9. return dog.name;
  10. };

上面的代码里先是创建了一个空的对象,然后向它添加了属性和方法。你还可以修改属性的值,或是重新定义方法:

  1. dog.getName = function () {
  2. // redefine the method to return
  3. // a hardcoded value
  4. return "Fido";
  5. };

甚至删除属性:

  1. delete dog.name;

再加入新的属性和方法:

  1. dog.say = function () {
  2. return "Woof!";
  3. };
  4. dog.fleas = true;

这个例子一开始定义的是个空的对象,实际的情况下也可以在最初给这个对象定义一些内容:

  1. var dog = {
  2. name: "Benji",
  3. getName: function () {
  4. return this.name;
  5. }
  6. };

补充说明一下,上面提到的”空的对象“其实在JavaScript里并不”空“。因为当你声名了一个{}对象,它立即就从Object.prototype中继承了属性和方法,说它是个”空的对象“,意思是我们还没有给它定义自己的属性和方法而已。

2. 用JavaScript内置的构造函数创建Object对象
 再次说明一下,JavaScript里没有”类“这个概念。创建JavaScript对象时不需要有”蓝本“。在JavaScript里,对象的构造函数有点像”类“的定义,特别是在把构造函数用起来的时候。下面看一下用Literal和内置的构造函数这两种方法的具体做法:

  1. // one way -- using a literal
  2. var car = {goes: "far"};
  3. // another way -- using a built-in constructor
  4. // warning: this is an antipattern
  5. var car = new Object();
  6. car.goes = "far";

很明显,一行的Literal声名可以完成两行Contructor声名的工作。另外,Literal的方式也能体现JavaScript里对象的实际情况:其实就是一堆的键值对,而不是由一个蓝本”类“实例化而来。所以我们应该总是用Literal的方式来声名Object对象,而不是用 JavaScript内置的new Object()的方式。new Object()还有一个问题。当你给这个构造函数传递参数的时候,它可能会热心的帮你生成一个特殊类型的对象,这时可能会发生一些意思不到的问题:

  1. // Warning: antipatterns ahead
  2. // an empty object
  3. var o = new Object();
  4. console.log(o.constructor === Object); // true
  5.  
  6. // a number object
  7. var o = new Object(1);
  8. console.log(o.constructor === Number); // true
  9. console.log(o.toFixed(2)); // "1.00"
  10.  
  11. // a string object
  12. var o = new Object("I am a string");
  13. console.log(o.constructor === String); // true
  14. // normal objects don't have a substring()
  15. // method but string objects do
  16. console.log(typeof o.substring); // "function"
  17.  
  18. // a boolean object
  19. var o = new Object(true);
  20. console.log(o.constructor === Boolean); // true

3. 自定义的构造函数来创建特定的对象
除了new Object()以外,我们也可以用自己编写构造函数来创建特定的对象,比如:

  1. var adam = new Person("Adam");
  2. adam.say(); // "I am Adam"

这段代码看起来很像是Java里创建Person对象。虽然语法相似,但在JavaScript里没有”类“,而且Person其实也不过只是个函数。下面就是Person这个用于构造对象的函数的定义方式:

  1. var Person = function (name) {
  2. this.name = name;
  3. this.say = function () {
  4. return "I am " + this.name;
  5. };
  6. };

当使用new关键字执行上面的函数时,发生了下面的几件事:

  • 一个空的对象被创建了出来;
  • 使这个对象继承Object.proptotype(JavaScript里的对象原型),并把对象的引用赋给this;
  • 在函数的最后隐式返回this引用。

也就是说:

  1. var Person = function (name) {
  2. // create a new object
  3. // using the object literal
  4. // var this = {};
  5. // add properties and methods
  6. this.name = name;
  7. this.say = function () {
  8. return "I am " + this.name;
  9. };
  10. // return this;
  11. };

上面的代码表明,new Person()对于JavaScript来说,并不是创建了一个类的实例,而是创建了一个新的函数,并把这个函数的引用交给了this。我们以后再谈谈 JavaScript里的函数与对象的关系,以及对象原型和继承,这里先看看say()方法。为了简化这个例子,我们为Person对象加入了say() 方法,但这种做法在效率上并不高:因为每个新的对象里的say方法都是一样的。对于这种情况,其实应该为Person的原型加入say()方法,而不是在创建的时候为每个对象加入相同的say方法:

  1. Person.prototype.say = function () {
  2. return "I am " + this.name;
  3. };

更清楚明白地说,其实构造函数创建的对象并不”空“,也就是说这里:

  1. // var this = {};

应该是创建了Object原型的一个拷贝才对:

  1. // var this = Object.create(Person.prototype);

当然,隐式的return如果被显式地加入,你就可以返回一个你想返回的任何对象,这时返回的就不是this引用了。比如:

  1. var Objectmaker = function () {
  2. // this `name` property will be ignored
  3. // because the constructor
  4. // decides to return another object instead
  5. this.name = "This is it";
  6. // creating and returning a new object
  7. var that = {};
  8. that.name = "And that's that";
  9. return that;
  10. };
  11. // test
  12. var o = new Objectmaker();
  13. console.log(o.name); // "And that's that"

JavaScript基础Literal 与 Constructor(008)的更多相关文章

  1. Javascript基础回顾 之(三) 面向对象

    本来是要继续由浅入深表达式系列最后一篇的,但是最近团队突然就忙起来了,从来没有过的忙!不过喜欢表达式的朋友请放心,已经在写了:) 在工作当中发现大家对Javascript的一些基本原理普遍存在这里或者 ...

  2. Javascript基础知识总结一

    Javascript基础知识总结一 <!DOCTYPE html> <html> <head lang="en"> <meta chars ...

  3. javascript基础语法——表达式

    × 目录 [1]原始表达式 [2]复杂表达式 前面的话 一般地,关于javascript基础语法,人们听得比较多的术语是操作符和语句.但是,其实还有一个术语经常使用,却很少被提到,这就是javascr ...

  4. JavaScript基础---语言基础(1)

    写在前面: 通过四篇博客把JS基础中的基础整理一下,方便自己查阅,这些内容对于实际项目开发中也许并不会在意,但是作为JS的语言基础,自觉还是应该熟悉.在完成这三篇博客(JavaScript基础---语 ...

  5. Web前端-JavaScript基础教程上

    Web前端-JavaScript基础教程 将放入菜单栏中,便于阅读! JavaScript是web前端开发的编程语言,大多数网站都使用到了JavaScript,所以我们要进行学习,JavaScript ...

  6. javascript基础修炼(11)——DOM-DIFF的实现

    目录 一. 再谈从Virtual-Dom生成真实DOM 二. DOM-Diff的目的 三. DOM-Diff的基本算法描述 四. DOM-Diff的简单实现 4.1 期望效果 4.2 DOM-Diff ...

  7. JavaScript基础视频教程总结(001-010章)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  8. JavaScript基础视频教程总结(041-050章)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  9. 2、JavaScript 基础二 (从零学习JavaScript)

     11.强制转换 强制转换主要指使用Number.String和Boolean三个构造函数,手动将各种类型的值,转换成数字.字符串或者布尔值. 1>Number强制转换 参数为原始类型值的转换规 ...

随机推荐

  1. Shiro (Shiro + JWT + SpringBoot应用)

    Shiro (Shiro + JWT + SpringBoot应用) 目录 Shiro (Shiro + JWT + SpringBoot应用) 1.Shiro的简介 2.Shiro + JWT + ...

  2. Java实现 LeetCode 777 在LR字符串中交换相邻字符(分析题)

    777. 在LR字符串中交换相邻字符 在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作.一次移动操作指用一个"L ...

  3. Java实现 LeetCode 515 在每个树行中找最大值

    515. 在每个树行中找最大值 您需要在二叉树的每一行中找到最大的值. 示例: 输入: 1 / \ 3 2 / \ \ 5 3 9 输出: [1, 3, 9] /** * Definition for ...

  4. Java实现 蓝桥杯VIP 基础练习 芯片测试

    问题描述 有n(2≤n≤20)块芯片,有好有坏,已知好芯片比坏芯片多. 每个芯片都能用来测试其他芯片.用好芯片测试其他芯片时,能正确给出被测试芯片是好还是坏.而用坏芯片测试其他芯片时,会随机给出好或是 ...

  5. Java实现 LeetCode 434 字符串中的单词数

    434. 字符串中的单词数 统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符. 请注意,你可以假定字符串里不包括任何不可打印的字符. 示例: 输入: "Hello, my nam ...

  6. pi-star镜像 下载地址

    Pi-Star_NanoPi_Air_V3.4.17_09-Jan-2019.zip nanopi air点这里  Pi-Star_NanoPi_V3.4.17_09-Jan-2019.zip nan ...

  7. web静态页面资源访问路径问题

    我使用的是idea,今天搭建一个项目时遇见了css和js路径错误,导致浏览器获取不到资源路径 这是我最开始写的路径 <link href="/main/loginMain.css&qu ...

  8. linux pinmux 引脚多路复用驱动分析与使用

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/code_style/article/de ...

  9. SpringCloud Alibaba (一):序言

    为什么要转用SpringCloud Alibaba? Spring Cloud Netflix项目进入维护模式 在2018年底时,Netflix宣布Hystrix进入维护模式.自2016年以来,Rib ...

  10. Tournament Chart【模拟+vector+map+string】

    Tournament Chart 传送门:链接  来源:UPC10889 题目描述 In 21XX, an annual programming contest, Japan Algorithmist ...