zoukankan      html  css  js  c++  java
  • 标准库》第三章 包装对象和Boolean对象

    第三部分  标准库

    ***************第三章   包装对象和Boolean对象*******************


    一、包装对象的定义
    【1】有人说,JavaScript语言“一切皆对象”,数组和函数本质上都是对象,就连三种原始类型的值——数值、字符串、布尔值——在一定条件下,也会自动转为对象,也就是原始类型的“包装对象”。

    所谓“包装对象”,就是分别与数值、字符串、布尔值相对应的Number、String、Boolean三个原生对象。这三个原生对象(意思是原生对象的构造函数或者说原生类)可以把原始类型的值变成(包装成)对象。

    这些构造函数本身是被赋予了类 的概念,然后函数这种语法结构在js语法体系中由又算是归到复合类型、也就是对象这个数据类型下的

    var v1 = new Number(123);
    var v2 = new String('abc');
    var v3 = new Boolean(true);


    上面代码根据原始类型的值,生成了三个对象,与原始值的类型不同。这用typeof运算符就可以看出来。

    typeof v1 // "object"
    typeof v2 // "object"
    typeof v3 // "object"

    v1 === 123 // false
    v2 === 'abc' // false
    v3 === true // false

    typeof (Number(123))
    "number"

    typeof (String('abc'))"string"

    typeof (Boolean(true))
    "boolean"
    【2】JavaScript设计包装对象的最大目的,首先是使得JavaScript的“对象”涵盖所有的值。也是为了使用方便,所有值都可以用做对象。
    其次,使得原始类型的值可以方便地调用特定方法。

    Number、String和Boolean如果不作为构造函数调用(即调用时不加new),常常用于将任意类型的值转为数值、字符串和布尔值。
    Number(123) // 123
    String('abc') // "abc"
    Boolean(true) // true

    【这三个对象作为构造函数使用(带有new)时,可以将原始类型的值转为对象;作为普通函数使用时(不带有new),可以将任意类型的值,转为原始类型的值。】
    那么针对我们自己写的构造函数,带New和不带又有什么区别呢可能没有区别,内部机制不详

    【二.包装对象实例的方法】方法是部署在包装对象原型上的
    包装对象实例可以使用Object对象提供的原生方法,而且是以自身调用,主要是valueOf方法和toString方法。因为Number String Boolean这三个原生对象都是Object对象派生来的, 它们的原形继承了Object.prototype的属性和方法


    【1 valueOf()】

    valueOf方法返回包装对象实例对应的原始类型的值。

    new Number(123).valueOf()  // 123
    new String("abc").valueOf() // "abc"
    new Boolean("true").valueOf() // true

    【2 toString()】
    toString方法返回实例对应的字符串形式。

    new Number(123).toString() // "123"
    new String("abc").toString() // "abc"
    new Boolean("true").toString() // "true"


    【三、原始类型的自动转换】

    原始类型的值,可以自动当作对象调用,即调用各种对象的方法和参数。这时,JavaScript引擎会自动将原始类型的值转为包装对象,在使用后立刻销毁。

    比如,字符串可以调用length属性,返回字符串的长度。
    'abc'.length // 3

    var str = 'abc';
    str.length // 3

    // 等同于
    var strObj = new String(str)
    // String {
    //   0: "a", 1: "b", 2: "c", length: 3, [[PrimitiveValue]]: "abc"
    // }
    strObj.length // 3

    上面代码中,字符串abc的包装对象有每个位置的值、有length属性、还有一个内部属性[[PrimitiveValue]]保存字符串的原始值。这个[[PrimitiveValue]]内部属性,外部是无法调用,仅供ValueOf或toString这样的方法内部调用。

    这个临时对象是只读的,无法修改。所以,字符串无法添加新属性。

    var s = 'Hello World';
    s.x = 123;
    s.x // undefined
    上面代码为字符串s添加了一个x属性,结果无效,总是返回undefined。
    另一方面,调用结束后,临时对象会自动销毁。这意味着,下一次调用字符串的属性时,实际是调用一个新生成的对象,而不是上一次调用时生成的那个对象,所以取不到赋值在上一个对象的属性。
    如果想要为字符串添加属性,只有在它的原型对象String.prototype上定义(参见《面向对象编程》一章)。
    说白了就是String构造函数、类的原形上的方法


    这种原始类型值可以直接调用的方法还有很多(详见后文对各包装对象的介绍),除了前面介绍过的valueOf和toString方法,还包括三个包装对象各自定义在实例上的方法。。
    'abc'.charAt === String.prototype.charAt
    // true

    【注意:String、Number、Boolean三个包装对象原形上单独部署的方法未介绍】
    上面代码表示,字符串abc的charAt方法,实际上就是定义在String对象实例上的方法(关于prototype对象的介绍参见《面向对象编程》一章)。

    如果包装对象与原始类型值进行混合运算,包装对象会转化为原始类型(实际是调用自身的valueOf方法)。

    new Number(123) + 123 // 246
    new String('abc') + 'abc' // "abcabc"


    【四.自定义方法】

    【1】三种包装对象还可以在原型上添加自定义方法和属性,供原始类型的值直接调用。

    比如,我们可以新增一个double方法,使得字符串和数字翻倍。

    String.prototype.double = function () {
      return this.valueOf() + this.valueOf();
    };

    'abc'.double()
    // abcabc

    Number.prototype.double = function () {
      return this.valueOf() + this.valueOf();
    };

    (123).double()
    // 246
    【2】上面代码在123外面必须要加上圆括号,否则后面的点运算符(.)会被解释成小数点。


    但是,这种自定义方法和属性的机制,只能定义在包装对象的原型上,如果直接对原始类型的变量添加属性,则无效。

    var s = 'abc';

    s.p = 123;
    s.p // undefined

    上面代码直接对字符串abc添加属性,结果无效。主要原因是上面说的,这里的包装对象是自动生成的,赋值后自动销毁,
    你根本没有机会再次使用它,所以最后一行实际上调用的是一个新的包装对象。


    【五.Boolean对象】

    【1】概述
    Boolean对象是JavaScript的三个包装对象之一。作为构造函数,它主要用于生成布尔值的包装对象的实例。
    var b = new Boolean(true);

    typeof b // "object"
    b.valueOf() // true

    var a = true;

    typeof a   //
    "boolean"

    上面代码的变量b是一个Boolean对象的实例,它的类型是对象,值为布尔值true。这种写法太繁琐,几乎无人使用,直接对变量赋值更简单清晰。(但是这样赋值用typeof检查会发现史原始类型)

    var b = true;

    注意,false对应的包装对象实例,布尔运算结果也是true。

    if (new Boolean(false)) {
      console.log('true');
    } // true

    if (new Boolean(false).valueOf()) {
      console.log('true');
    } // 无输出

    【上面代码的第一个例子之所以得到true,是因为false对应的包装对象实例是一个对象,进行逻辑运算时,被自动转化成布尔值true(因为所有对象对应的布尔值都是true)。而实例的valueOf方法,则返回实例对应的原始值,本例为false。】

    【2 Boolean函数的类型转换作用】

    Boolean对象除了可以作为构造函数,还可以单独使用,将任意值转为布尔值。这时Boolean就是一个单纯的工具方法。

    Boolean(undefined) // false
    Boolean(null) // false
    Boolean(0) // false
    Boolean('') // false
    Boolean(NaN) // false

    Boolean(1) // true
    Boolean('false') // true
    Boolean([]) // true
    Boolean({}) // true
    Boolean(function () {}) // true
    Boolean(/foo/) // true

    上面代码中几种得到true的情况,都值得认真记住。

    使用双重的否运算符(!)也可以将任意值转为对应的布尔值。
    否运算符后面应该是布尔类型的值,JS引擎会自动调用类型转换的方法


    使用双重的否运算符(!)也可以将任意值转为对应的布尔值。

    !!undefined // false
    !!null // false
    !!0 // false
    !!'' // false
    !!NaN // false
    !!1 // true
    !!'false' // true
    !![] // true
    !!{} // true
    !!function(){} // true
    !!/foo/ // true

    if (Boolean(false)) {
      console.log('true');
    } // 无输出

    if (new Boolean(false)) {
      console.log('true');
    } // true

    if (Boolean(null)) {
      console.log('true');
    } // 无输出

    if (new Boolean(null)) {
      console.log('true');
    } // true

    new Boolean(null)
    【在实例化对象的时候如果括号内不是预期的数据类型,
    会先执行一个工具函数的转化类型的功能再实例化成为true或者false的包装对象】



  • 相关阅读:
    hdu 1017 A Mathematical Curiosity 解题报告
    hdu 2069 Coin Change 解题报告
    hut 1574 组合问题 解题报告
    hdu 2111 Saving HDU 解题报
    hut 1054 Jesse's Code 解题报告
    hdu1131 Count the Trees解题报告
    hdu 2159 FATE 解题报告
    hdu 1879 继续畅通工程 解题报告
    oracle的系统和对象权限
    oracle 自定义函数 返回一个表类型
  • 原文地址:https://www.cnblogs.com/xsfx/p/7128667.html
Copyright © 2011-2022 走看看