《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!");
原文地址:https://www.cnblogs.com/liubei/p/JavascriptModeLog2.html