《JavaScript 模式》读书笔记(3)— 字面量和构造函数1

新的篇章开始了,本章开始,所有的内容都是十分有价值和意义的。本章主要的内容包括对象字面量、构造函数、数组字面量、正则字面量、基本值类型字面量以及JSON等。在大家的工作和实际应用中也有一定的指导意义。

大家好,又见面了,我是你们的朋友全栈君。

  新的篇章开始了,本章开始,所有的内容都是十分有价值和意义的。本章主要的内容包括对象字面量、构造函数、数组字面量、正则字面量、基本值类型字面量以及JSON等。在大家的工作和实际应用中也有一定的指导意义。

 

一、对象字面量

  我们直接来先看一下代码:

// 开始时定义一个空对象
var dog = {};

// 向dog对象添加一个属性
dog.name = "Benji";

// 现在,向dog对象添加一个方法
dog.getName = function() {
    return dog.name;
};

// 前面的例子中,dog对象开始是干净的状态,即一个空对象(这里的空对象是指除了继承以外的属性,并没有自身的属性)。
// 然后可以向该对象添加一个属性和一个方法。在程序生命周期的任何时候,都可以执行以下操作。

// 改变属性和方法的值:
dog.getName = function() {
    // 重新定义返回该方法
    // 返回一个硬编码的值
    return "Fido";
};

// 完全删除属性/方法:
delete dog.name;

// 添加更多的属性和方法:
dog.say = function () {
    return "Woof!";
};

dog.fleas = true;

  当然,并不要求必须从空对象开始。对象字面量模式可以使您在创建对象时向其添加函数:

var dog = {
    name:"Benji",
    getName:function() {
        return this.name;
    }
};

  ok,上面的例子,就是一个标准的对象字面量写法,对象字面量语法如下:

    1、将对象包装在打括号中。

    2、对象中以逗号分隔属性和方法。在最后的名称-值的尾随逗号是允许的,但是在一些特殊的浏览器下会报错,所以请尽量不要这样。

    3、用冒号来分隔属性的名称和属性的值。

    4、当给变量赋值时,请不要忘记右大括号“}”后的分号。

 

来自构造函数的对象

  我们先来看一下,如何创建一个对象:

// 第一种方法:使用字面量:
var car = {goes:'far'};

// 另一种方法:使用内置构造函数-这是一个反模式,不要应用!
var car = new Object();
car.goes = "far";

  上面的两种创建对象的方式,尤其注意,不要使用内置构造函数来创建对象。字面量表示发的显著优点在于它仅需要输入更短的字符。优先选择字面量模式创建对象的另一个原因在于:它强调了该对象仅仅是一个可变哈希映射,而不是从对象中提取的属性或方法。

  与使用object构造函数相对,使用字面量的另一个原因在于它并没有作用域解析。因为可能以同样的名字创建了一个局部构造函数,解释器需要从调用Object()的位置开始一直向上查询作用域链,而不是从对象中提取的属性或方法。

 

对象构造函数捕捉

  我们不会使用对象构造函数去创建对象,但是我们应该了解对象构造函数的“特征”。这里的涉及到的“特征”在于,Object()构造函数仅接受一个参数,并且还依赖传递的值,该Object()可能会委派另一个内置构造函数来创建对象,并且返回了一个并非期望的不同对象。

// 以下是反模式

// 一个空对象
var o = new Object();
console.log(o.constructor === Object); //true

// 一个数值对象
var o = new Object(1);
console.log(o.constructor === Number); //true
console.log(o.toFixed(2)); //"1.00"

// 一个字符串对象
var o = new Object('I am a String');
console.log(o.constructor === String);// true

// 一般的对象并没有substring()方法
// 但是字符串对象都有该方法
console.log(typeof o.substring); // "function"

// 一个布尔对象
var o = new Object(true);
console.log(o.constructor === Boolean); //true

  我们看上面的代码,将数字、字符串、布尔值传递到new Object()构造函数中,其结果是获得了不同构造函数所创建的对象。就拿最后一个创建一个Boolean对象来说,实际上,真正执行创建的内置构造函数并不是Object(),而是Object()委派Boolean()构造函数创建的。

  当传递给Object()构造函数的值是动态的,并且直到运行时才能确定其类型时,Object()构造函数的这种行为可能会导致意料不到的结果。因为,最后再强调一遍,不要使用new Object()构造函数!

 

二、自定义构造函数

    除了对象字面量模式和内置的构造函数以外,可以使用自己的构造函数来创建对象:

var adam = new Person("Adam");
adam.say();

  这里的Person,只是一个函数而已:

var Person = function(name) {
    this.name = name;
    this.say = function () {
        return "I am" + this.name;
    };
};

  当使用new操作符调用构造函数时,函数内部会发生以下情况:

    1、创建一个空对象并且this变量引用了该对象,同时还继承了该函数的原型。

    2、属性和方法对加入到this引用的对象中。

    3、新创建的对象由this所引用,并且最后隐式的返回this(如果没有显示的返回其它对象)。

  看起来就像这样:

var Person = function(name) {
    // 使用对象字面量模式创建一个新对象
    // var this = {};
    // 向this添加属性和方法
    this.name = name;
    this.say = function () {
        return "I am" + this.name;
    };

    // return this;
};

  在上面的例子中,为了简单起见,将say()方法添加到了this中。其造成的结果是在任何时候调用new Person()时都会在内存中创建一个新的函数。这种方法的效率显然非常低下,因为多个实例之间的say()方法实际上并没有改变,更好的选择是将方法添加到Person类的原型中。

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

  这里要强调的一点事,可重用的成员,比如可重用的方法,都应该放置到对象的原型中。

  要注意:

// var this = {};

  这段代码并不是真相的全部。因为“空”对象实际上并不空,它已经从Person的原型的原型中继承了许多成员。因此,它更像是下面的语句:

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

  Object.create会在后续的内容中进一步讨论。

 

构造函数的返回值

  当使用new操作符创建对象时,构造函数总是返回一个对象;默认情况下返回的是this所引用的对象。如果在构造函数中并不向this添加任何属性,将返回“空”对象(这里的空,指的是除了从构造函数的原型中所继承的成员以外)。

  构造函数将隐式返回this,甚至于在函数中没有现实的加入return语句。但是,可以根据需要返回任意其他对象。比如:

var Objectmaker = function () {
    // 下面的“name”属性将被忽略
    // 这是因为构造函数决定改为返回另一个对象
    this.name = "This is it";
    // 创建并返回一个新对象
    var that = {};
    that.name = "And that's that";
    return that;
}
// 测试
var o = new Objectmaker();
console.log(o.name);

  正如上面所看到的,可以在构造函数中自由的返回任意对象,只要它是一个对象。试图返回并非对象的值,这虽然不会造成错误,但是函数却会简单的忽略该值,相反,构造函数将会返回this所引用的对象。

 

  好了,我们今天的内容就先到这里。后面再继续,以防一篇的文章内容过长。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/124396.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • VMware安装ESXI

    VMware安装ESXI

  • set是什么_js把参数放入request

    set是什么_js把参数放入request1.Accept:image/gif,image/x-xbitmap,image/jpeg,image/pjpeg,application/vnd.ms-powerpoint,application/vnd.ms-excel,application/msword,application/x-shockwave-flash,/2.Accept-Language:zh-cn3.Accept-Encoding:gzip,deflate4.User-Agent:Mozilla/

  • 完全卸载tensorflow (pip安装)[通俗易懂]

    完全卸载tensorflow (pip安装)[通俗易懂]查看tensorflow版本sudopipshowtensorflow卸载:sudopipuninstallprotobufsudopipuninstalltensorflow

  • 数据库 之 关系模式范式

    数据库 之 关系模式范式主要有6种范式:第一范式(1NF),第二范式(2NF),第三范式(3NF),巴德斯科范式(BCNF),第四范式(4NF),第五范式(5NF),按从左至右的顺序一种比一种要求更严格。要符合某一种范式必须

  • C语言的seekg函数,C++ seekg函数用法详解[通俗易懂]

    C语言的seekg函数,C++ seekg函数用法详解[通俗易懂]很多时候用户可能会这样操作,打开一个文件,处理其中的所有数据,然后将文件倒回到开头,再次对它进行处理,但是这可能有点不同。例如,用户可能会要求程序在数据库中搜索某种类型的所有记录,当这些记录被找到时,用户又可能希望在数据库中搜索其他类型的所有记录。文件流类提供了许多不同的成员函数,可以用来在文件中移动。其中的一个方法如下:seekg(offset,place);这个输入流类的成员函数的名字se…

  • 微信公众号基本配置url_配置url

    微信公众号基本配置url_配置url启用开发模式需要先成为开发者,而且编辑模式和开发模式只能选择一个,进入微信公众平台-开发模式,如下:需要填写url和token,当时本人填写这个的时候花了好久,我本以为填写个服务器的url就可以了(

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号