zoukankan      html  css  js  c++  java
  • 《javascript模式--by Stoyan Stefanov》书摘--字面量和构造函数

    二、字面量和构造函数

    1,能够使用对象字面量时,就没理由使用new Object构造函数

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

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

    2、自定义构造函数

    可重用的成员,比如可重用方法,都应该放置到对象的原型中

    3、构造函数的返回值

    在构造函数中可以自由返回任意对象,只要它是一个对象。如果不是,并不会造成错误,相反,构造函数将会返回this所引用的对象。

    4、构造函数避免使用this

    function Sayhello() {
        this.name = "finder";    //等同window.name  
        return this;
    }
    
    //   以上虽然在ES5得到解决,并且在严格模式中this不会指向 全局变量
    //     推荐以下方式
    function Sayhello() {
        var that = {};
        that.name = "finder";    //
        return that;
    }

    5、自调用构造函数

    function Sayhello (){
        if ( !(this instanceof Sayhello)) {
               return new Sayhello();
          }  
    }
    
    //  通用方法
    function Sayhello (){
        if ( !(this instanceof arguments.callee)) {
               return new arguments.callee();
          }  
    }

    6、数组构造函数的特殊性(数组字面量表示更为安全)

    //   一个元素数组
    var a = [3];
    console.log(a.length);        //   1
    console.log(a[0]);            //   3
    
    //   三个元素的数组
    var a = new Array(3);
    console.log(a.length);        //   3
    console.log(typeof a[0]);              //"undefined"
    
    //  如果传入一个浮点数?worst...
    var a = [3.14];
    console.log(a[0]);        //   3.14
    var a = new Array(3.14);
    console.log(a.length);      //  RangeError: Invalid array length

    7、检查数组性质

    参考地址:http://www.nowamagic.net/librarys/veda/detail/1250

    //  数组也是对象
    typeof [];   //   "object"
    
    //   支付宝同学在用的
    if (value instanceof Array ||
        (!(value instanceof Object) &&
        (Object.prototype.toString.call((value)) == '[object Array]') ||
        typeof value.length == 'number' &&
        typeof value.splice != 'undefined' &&
        typeof value.propertyIsEnumerable != 'undefined' &&
        !value.propertyIsEnumerable('splice'))) {
        return 'array';
    }
    
    //  最直接的、简单的方式(在不同 iframe 中创建的 Array 并不共享 prototype)
    var arr = [];
    arr instanceof Array; // true
    arr.constructor == Array; //true
    
    //  基于iframe的情况 使用 Douglas Crockford 的方法是可以解决这个问题(《JavaScript 语言精粹》P61)
    var is_array = function(value) {
        return value &&
            typeof value === 'object' &&
            typeof value.length === 'number' &&
            typeof value.splice === 'function' &&
            !(value.propertyIsEnumerable('length'));
    };
    
    //  更简单的方法,也是jQuery 正在使用的。淘宝的 kissy 也是使用这种方式
    var isArray = function(obj) {
        return Object.prototype.toString.call(obj) === '[object Array]';
    }
    
    //   大而全而cool  判断类型
    var is = function (obj,type) {
            return (type === "Null" && obj === null) ||
            (type === "Undefined" && obj === void 0 ) ||
            (type === "Number" && isFinite(obj)) ||
             Object.prototype.toString.call(obj).slice(8,-1) === type;
    }
    // jQuery,Ext3的写法,也是推荐的写法
    isArray : function(v){
                return toString.apply(v) === '[object Array]';
            }  

     8、JSON

    json和文字对象之间唯一的语法差异:属性名必需包装在引号中才能成为合法的JSON,而在对象字面量中,仅当属性名称不是有效的标识符时才会需要引号,比如:字符之间的空格{"first name": "javascript"}

    此外,在JSON字符串中,不能使用函数或正则表达式字面量

    9、使用JSON

    JSON.parse()方法是ES5的一部分,一般情况下可以使用JSON.org库(http://www.json.org/json2.js)以访问JSON对象及其方法。

    //   JQuery的parseJSON()方法
    var data = '{"name": “finder”}';
    console.log( JQuery.parseJSON( data.name ) );  //  "finder"
    
    //  与JSON.parse()相对的方法JSON.stringify()

    10、正则表达式字面量

    javasript正则表达式也是对象  

    typeof ///;    //"object"

    // 创建正则表达式
    var re = /\/g; // 字面量方法创建 推荐
    var re = new RegExp("\\", "gm"); // 构造函数方法创建

    11、正则表达式语法

    用斜杠来包装用于匹配的正则表达式模式,在第二个斜杠之后,可以将该模式改为不加引号的字母形式:

    • g----全局匹配
    • m---多行
    • i----大小写敏感的匹配
    //  正则表达式使用
    var name = "fin123d456e789r".replace(/[0-9]/gi, "");
    console.log(name);    // "finder"

    使用new RegExp()的原因:某些场景无法事先确定模式,而只能在运行时以字符串方式创建。

    正则表达式字面量各构造函数之间的其中一个区别在于:字面量在解析时只有一次创建了一个对象,如下例子()

    //经测试字面量创建共享一个对象的情况在浏览器里已经不存在了,包括IE6
    function getName () {
        var person = /[a-z]/;
        person.name = "finder";
        return person;
    }
    
    var firstName = getName(),
        realName = getName();
    
    console.log(firstName === realName);   // false   
    firstName.name = "liubei";
    console.log(realName.name)      //   "finder"

    如代码所示,这样的情况如果在浏览器环境中就可以不用考虑了

    注:调用RegExp()时不使用new与使用new效果是相同的

    12、基本值类型包装器

    javascript有五个基本的值类型:数字,字符串,布尔值,nullt和undefined。除了null和undefined以外,其他三个具有所谓的基本包装对象(primitive wrapper object)。可以使用内置构造函数Number(),String(),Boolean()创建包装对象。

    为了基本(primitive)数字和数字对象(object)之间的差异,来个例子

    //  一个基本类型
    var n = 6;
    console.log(typeof n);    //  number 
    
    // 一个数值Number对象
    var nbj = new Number(6)j;
    console.log(typeof nbj);    //  object

    当基本类型使用对象方法的时候它会自动临时转换为一个对象

    //  用来作为对象的基本字符串
    var name = "finder";
    console.log(name.toUpperCase());      //  FINDER
    
    //   值本身可以作为一个对象
    "finder".slice(0,4);          //     "find"
    
    //   与数值的方法相同
    (22/7).toPrecision(3);        //  "3.14"

    通常使用包装对象的原因:有扩充值以及持久保存状态的需要,由于基本值类型不是对象,不可能扩充属性

    //    基本字符串
    var greet = "hello I'm finder";
    
    //   使用split自动从基本数据类型转换为对象
    greet.split(" ")[0];   //  "hello"
    
    //   试图增加一个原始数据类型并不会导致错误
    greet.smile = true;
    
    //   但,它并不是实际运行。。
    typeof greet.smile;  //    "undefined"

    在使用没有带new操作符时,它将转换为一个基本类型

    typeof Number(6)      //   "number"
    typeof Number("6")   //   "number"
    typeof Number(new Number());    //   "number"
    typeof String(6);   //  "string"
    typeof Boolean(1);    //   "boolean"
    
    //  神奇的布尔值~~
    Boolean(1).toString();       //  "true"
    Boolean(0).toString();      //   "false"
    Boolean().toString();         //   "false"
    
    //   下面的可以猜到吗???
    Boolean(4).toString();    //    "true"
    Boolean(-4).toString();    //    "true"
    Boolean(0.1).toString()   //   "true"

    13、错误对象

    javascript有一些内置错误函数(error constructor),比如Error(),SyntaxError(),TypeError以及其他,这些都带有throw语句,通过这些错误构造函数创建的错误对象具有下列属性:

    name:名称属性,“Error”/更为专门的构造函数,比如"RangeError"

    message:字符串

    错误对象还有一些其他属性,因浏览器实现不一,并不可靠。

    另外,throw适用于任何对象,

    try{
        //   抛出错误
        throw{
          name : string,
          message : “oop”,
          extra : string,
          remedy : genericErrorHandler   // 指定应该处理该错误的函数  
        }  
    }catch(e){
        //   通知用户
        alert(e.message);    //   "oop"
        e.remedy();    //    调用函数genericErrorHandler
    }
    // 错误构造函数心函数的形式调用(不带new)时,其表现行为与构造函数(带new)相同,并且返回同一个错误对象

    14、常用构造函数

    一般情况下,除了Date()构造函数以外,很少需要内置构造函数,下面为常用函数

    //    Built-in constructors   (avoid)
    var o = new Object();
    var a = new Array();
    var re = new RegExp("[a-z]", "g");
    var s = new String();
    var n = new Number();
    var b = new Boolean();
    throw new Error("ooooooooops!");
    
    // Literals an primitives (prefer)
    var o = {};
    var a = [];
    var re = /[a-z]/g;
    var s = "";
    var n = 0;
    var b = false;
    throw{
        name : "Error",
        message: "oooooooooops!!!"    
    }
    //  or
    throw Error("oooooooops!");
  • 相关阅读:
    JS中的call()和apply()方法
    jQuery的deferred对象详解
    浅谈postMessage多页面监听事件
    js 的try catch
    浅谈JavaScript DOM编程艺术读后感和一点总结
    人人都看得懂的正则表达式教程
    JavaScript面向对象精要
    配置Tomcat配置路径
    IOS, Android, Java Web Rest : RSA 加密和解密问题
    说说secondarynamenode作用和配置
  • 原文地址:https://www.cnblogs.com/liubei/p/JavascriptModeLog2.html
Copyright © 2011-2022 走看看