您的位置:首页 > Web前端 > JavaScript

JavaScript模式 读书笔记二

2015-11-03 00:00 721 查看

第三章 字面量和构造函数

对象字面量

[code=plain]//开始定义一个空对象
var dog = {};

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

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

dog.getName = function () {
//重新定义该返回方法
//返回一个硬编码的值
return "Lilu";
}
console.log(dog);
console.log(dog.getName);
console.log(dog.getName());

delete dog.name; //删除属性
console.log(dog);

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

console.log(dog);


[code=plain]//即使最简单的{}对象也具有从Object.prototype继承的属性和方法
if(typeof Object.prototype.clone==="undefined"){
Object.prototype.clone=function(){
alert('克隆');
};
}
var dog={};
console.log(dog);
dog.clone()


对象字面量语法

来自构造函数的对象

可以使用自己的构造函数,或使用一些类似Object(),Date(),String()的内置构造函数创建对象

[code=plain]//第一种方法 使用字面量
var car={goes:"far"};
console.log(car);

//另一种方法 使用内置构造函数
var car2=new Object();
car2.goes="far";
console.log(car2);

//另一种方法 使用内置构造函数
var car3=new String();
car3.goes="far";
console.log(car3);

var car4=new Date();
car4.goes="far";
console.log(car4);


对象构造函数捕捉

不要使用new Object构造函数,应该使用简单可靠的对象字面量模式。

[code=plain]//警告:前面的反模式

//一个空对象
var o=new Object();
console.log(o.constructor);
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 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;


自定义构造函数

[code=plain]//Person构造函数的定义
var Person = function (name) {
this.name = name;
this.say = function (){
return "I am " + this.name;
};

};

var lilu=new Person("Lilu");
lilu.say(); //输出为I am Lilu
console.log(lilu);
console.log(lilu.say());


代码改进

[code=plain]//Person构造函数的定义
var Person = function (name) {
this.name = name;

};

Person.prototype.say=function(){
return "I am "+this.name;
}
var lilu=new Person("Lilu");
lilu.say(); //输出为I am Lilu
console.log(lilu);
console.log(lilu.say());


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

构造函数的返回值

构造函数将隐式返回this,甚至在函数中没有显式的加入return语句。

[code=plain]var Objectmaker=function(){
this.name="haha";
};

var o=new Objectmaker();
console.log(o.name) // 输出为 And that's that


但构造函数中可以自由的返回任意对象,只要它是一个对象。

[code=plain]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) // 输出为 And that's that


强制使用new模式

构造函数仍然只是函数,只不过它以new的方式调用。

忘记使用new操作符会导致构造函数中的this指向全局对象。

[code=plain]//构造函数
function Waffle(){
this.tastes="yummy";
}

//定义一个新对象
var good_morning=new Waffle();
console.log(typeof good_morning);  //object
console.log(good_morning.tastes);  //yummy

//反模式
//方剂使用new操作符
var good_morning=Waffle();
console.log(typeof morning); //将输出undefined
console.log(window.tastes);  //将输出yummy


命名约定

构造函数名称中首字母大写,普通函数和方法的名称中的首字母变成小写

使用that

[code=plain]function Waffle(){
var that={};
that.tastes="yummy";
return that;
}

var good_morning=Waffle();
console.log(typeof good_morning);
console.log(good_morning.tastes);


对于简单对象,甚至不需要用类似that这样的局部变量

[code=plain]function Waffle(){

return {
tastes:"yummy"
};

}

var good_morning=Waffle();
console.log(typeof good_morning);
console.log(good_morning.tastes);


这种模式(忘记写new)的问题在于它会丢失到原型的链接,任何您添加到Waffle()原型的成员,对象都是不可用的。

自调用构造函数

[code=plain]function Waffle(){
if(!(this instanceof Waffle)){

return new Waffle();
}

this.tastes="yummy";
}

Waffle.prototype.wantAnother=true;
var first=Waffle();
var second=new Waffle();

console.log(first.tastes);  //输出yummy
console.log(second.tastes); //输出yummy


数组字面量

[code=plain]//具有三个元素的数组
//警告:反模式
var a=new Array("itsy","bitsy","spider");

//完全相同的数组
var a=["itsy","bitsy","spider"];

console.log(typeof a); //输出object,这是由于数组本身也是对象类型
console.log(a.constructor===Array); //输出true


数组字面量语法

数组字面量表示法 (Array literal notation)

数组构造函数的特殊性

当向Array()构造函数传递单个数字时,它设置了数组的长度,但干数组中并没有实际的元素。

[code=plain]//具有一个元素的数组
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


向该构造函数传递一个浮点数,情况变得更加糟糕。

[code=plain]//使用数组字面量
var a=[3.14];
console.log(a[0]); //3.14

var a=new Array(3.14); //输出RangeError:invalid array length(范围错误,不合法的数组长度)
console.log(typeof a); //输出undefined


尽量避免使用Array()构造函数,坚持使用数组字面量。

某些情况下使用Array()构造函数 比如返回一个具有255个空白字符的字符串 var white=new Array(256).join(' ');

检查数组性质

ECMAScript5定义了一个新的方法Array.isArray()检测数组性质

[code=plain]Array.isArray([]); //true

//试图以一个类似数组的对象欺骗检查
Array.isArray({
length:1,
"0":1,
slice:function(){}
}); //false


向下兼容的写法

[code=plain]if(typeof Array.isArray==-"undefined"){
Array.isArray=function(arg){
return Object.prototype.toString.call(arg)==="[object Array]";
};
}


JSON

JSON与文字对象之间唯一的语法差异在于,在JSON中,属性名称需要包装在引号中才能成为合法的JSON.

而在对象字面量中,仅当属性名称不是有效的标识符时]才会需要引号。 如{"first name":"lilu"}

使用JSON

使用JSON.parse()方法解析字符串安全性更好。

[code=plain]//一个输入JSON字符串
var jstr='{"mykey":"my value"}';

//反模式
var data=eval('('+jstr+')');

//优先使用的方法
var data=JSON.parse(jstr);
console.log(data.mykey); // my value


在YUI3库里使用自带方法

[code=plain]//一个输入JSON字符串
var jstr='{"mykey":"my value"}';

//解析该字符串,并且使用一个YUI实例
YUI().use('json-parse',function(Y){
var data=Y.JSON.parse(jstr);
console.log(data.mykey);  //myvalue
});


在jQuery中存在一个parseJSON()方法

[code=plain]//一个输入JSON字符串
var jstr='{"mykey":"my value"}';

var data=jQuery.parseJSON(jstr);
console.log(data.mykey);


JSON.stringify()可以序列化对象或数组为一个JSON字符串

[code=plain]var dog={
name:"Fido",
dob:new Date(),
legs:[1,2,3,4]
};

var jsonstr=JSON.stringify(dog);
console.log(jsonstr);


正则表达式字面量

正则表达是也是对象

使用new RegExp()构造函数

使用正则表达式字面量 (优先原则字面量模式)

[code=plain]//正则表达式字面量
var re=/\\/gm;

//构造函数
var re=new RegExp("\\\\","gm");

console.log(re);


正则表达式字面量语法

g-全局匹配

m-多行

i-大小写敏感

var re=/pattern/gmi

调用类似String.prototype.replace()的方法

[code=plain]var no_letters="abc123XYZ".replace(/[a-z]/gi,"");
console.log(no_letters); //输出123


[code=plain]function getRE(){
var re=/[a-z]/;
re.foo="bar";
return re;
}
var reg=getRE();
var re2=getRE();

console.log(reg===re2); //
reg.foo="baz";
console.log(re2.foo); //

调用RegExp()使用new和不使用new的行为是相同的。

错误对象

[code=plain]try{
throw{
name:"MyErrorType",
message:"oops",
extra:"This was rather embarrassing",
remedy:genericErrorHandler
};
}catch(e){
alert(e.message);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: