一 对象字面量
1.1对象字面量的语法
1,对象键值对哈希表,在其他的编程语言中称之为“关联数组”,
2 键值对里面的值,可以是原始类型也可以是其他类型的对象,称之为属性,函数称之为方法
3 自定义对象的属性和方法是可以改变的,也可以删除
4 将对象包括在大括号中
2,对象中是键值对,键值对与键值对之间使用逗号分隔
3,键值对的键和值使用冒号分隔
1.2、来自构造函数的对象
下面介绍两种创建对象的方法:1,对象字面量;2,使用内置构造函数(反模式)
1,使用字面量创建对象
var car = {
goes: "far"
};
2,使用内置构造函数创建对象
var car=new Object();
car.goes='far';
对上述两种方法进行比较分析:
1,对象字面量方式强调:对象是一个可变的哈希映射表
2,内置构造函数强调:对象是由属性和方法组成的
3,使用内置构造函数模式可能会继承其他人编写的遗留代码,例如有人给Object构造函数追加了属性或者方法,那么内置构造函数模式就继承了非期望的属性和方法
4,内置构造函数模式中传递的参数不确定时,生成的对象类型也不确定,见下面的例子
var a = new Object();
console.log(a.constructor===Object);//true
var b = new Object(1);
console.log(b.constructor===Number);//true
var c = new Object("string");
console.log(c.constructor===String);//true
二自定义构造函数
1,使用new运算符调用一个函数,那么该函数就是自定义的构造函数,而生成的对象就是该自定义构造函数的实例
var Person = function (name) {
this.name = name;
this.say = function () {
return "I am" + this.name;
};
};
var a = new Person("Amanda");
2,下面我们来讲解一下使用new运算符调用函数的过程中发生了什么
(1)首先创建一个空的对象,并且this指针指向该对象,同时继承该对象的prototype,原型中的constructor指针指向自定义的构造函数,建立起来,实例与构造函数还有原型的关联
(2)其次自定义构造函数中的属性和方法加入到该对象中
(3)最后如果自定义构造函数中没有return语句,或者return语句返回的值不是对象,则隐式返回this所引用的对象,若return返回的值是对象,则直接返回该对象
function Person(){ this.name="jjj", this.age=18; this.sayName=function(){ console.log(this.name); } return this.name;//这里返回的是非对象,使用new运算符生成的实例会忽略该return语句,直接返回该实例 } var ss=new Person(); console.log(ss); //{name:"",age:....}
三 强制使用new的模式
调用自定义构造函数时,没有使用new运算符引发的后果,没有使用new运算符的话,this会指向window,那么原本属于实例的属性和方法,就会成为全局的变量和函数
var Person = function (name){
this.name ="Amanda";
this.say = function(){
return "I am"+this.name;
}
return this;
};
var a = Person();
console.log(name);//Amanda
console.log(a);//window
3.1 命名约定:自定义的构造函数,首字母要大写,其他的方法和函数的首字母小写
3.2 使用that:为了避免忘记使用new操作符,我们给出一种使用taht的方案
但是这种方案有一个问题,就是Person构造函数定义的原型上的方法和属性是无法访问到的,所以在3.3中给出了自调用构造函数的方法
function Person(){ var that={ }; that.name="jjj", that.age=18; that.sayName=function(){ console.log(that.name); } return that; } var ss=Person(); console.log(ss.name);//jjj
function Person(){ var that={ }; that.name="jjj", that.age=18; that.sayName=function(){ console.log(that.name); } return that; } Person.prototype.sayAge=function(){ console.log(this.age); }; var ss=Person(); console.log(ss.dd);//undefined
3.3 自调用构造函数
在判断this的类型不是Person的时候,我们使用new 再次调用Person,这里相当于调用了两次Person,所以222的log会出现两次,位于原型链上的sayAge方法也可以被ss实例调用到
function Person(){ console.log("222"); if(!(this instanceof Person)){ return new Person(); } console.log("111"); this.name="ssww"; this.age=18; } Person.prototype.sayAge=function(){ console.log(this.age); }; var ss=Person(); console.log(ss.name);//ssww ss.sayAge();//18
四数组字面量
4.1 数组字面量法
[1,2,{},"",true.....]
4.2 数组构造函数的特殊性(使用new Array构建数组)
在使用Array这个内置构造函数创建对象时,传入其中的参数必须是正整数,其含义是创建一个拥有n个元素的数组,这n个元素每个的值均为"undefined"
因此在传入的参数不是正整数时就会引起范围错误,说数组长度是不合法长度
new Array(3);//创建一个长度为3的数组,数组中的三个元素均为undefined
new Array(3.14);//如果传递的参数是一个非整数的字符,则会出现范围错误:不合法的数组长度
而我们使用Array创建对象时,传入其中的参数,往往是想传递第一个元素,而不是数组的长度,因此,为了避免出现这种情况,我们尽量避免使用Array这个内置构造函数来创建数组,建议使用数组字面量方法
4.3 检查数组性质:如何检测某一个对象是否是数组
判断一个值是不是数组,我们一般使用length或者看该值有没有slice方法,但是这个是不健壮的
ECMAScript5 定义了Ayyay.isAyyay方法,如果该值是数组就会返回true
为了兼容,我们对其做了一下完善
Array.isArray([]);//true; if( typeof Array.isArray==="undefined"){ Array.isArray=function(arg){ return Object.prototype.toString.call(arg)==="[object Array]"; } }
var arg=[1,2,3];
alert(Object.prototype.toString.call(arg));//[object Array]
五JSON
1,首先我们来看一下JSON的定义,JSON是JS对象表示法,与对象字面量很相似,都是键值对,
2,JSON与对象的区别:JSON中的属性名称必须使用引号包裹才能成为合法的JSON,而对象字面量是仅当属性名不是有效标示符的时候才需要引号,例如属性名称之间有空格
3 在JSON中,不能使用函数或者正则表达式字面量
var a={
"first name":"Jhon"
};//first与name之间的空格是非法字符,因此该对象字面量a的first name属性使用了引号
var a={
first:"Jhon"
};//该定义就属于对象字面量
var a={
"first":"Jhon"
};//而该定义就属于JSON
5.1 使用JSON
var jsonStr='{"name":"jjj","age":19}'; //eval('('+jsonStr+')');//反模式 $.parseJSON(jsonStr);
六 正则表达式字面量
1 创建正则表达式的两种方式:1 new RegExp()构造函数;2 使用正则表达式字面量
var reg=/\\/gm;//字面量 var reg=new RegRxp("\\\\","gm");//构造函数
6.1 正则表达式字面量语法
1 使用/来包装正则表弟模式
2 在第二个斜杠后面,可以将该模式修改为不加引号的字母形式,g:全局匹配;m:多行匹配;i:大小写敏感匹配
3 var re=/pattern/gmi;
七 基本值类型包装器
1 js中有5种基本的值类型,分别是数字,字符串,布尔,null和undefined,除了null和undefined,其他三种都是基本包装对象,可以使用Number,String,Boolean来创建包装对象
2 首先我们先来看一下基本数字和数字对象之间的差异
var n=100;
console.log(typeof n);//number
var m=new Number(100);
console.log(typeof m);//object
var a=Number(1);
//当使用包装类型的构造函数,却不使用new运算符时,包装构造函数则会将传递给它们的参数转化为一个基本类型值
console.log(typeof a);//number
3 包装对象包含一些属性和方法,例如:
数字对象的toFixed、toExponential、toPrecision等
字符串对象有substr、charAt、toLowerCase、length等
但是基本值类型在调用这些方法的时候,会在后台被临时转换成一个对象,并且表现的如同一个对象一样,在调用结束后,又转化为基本值类型
4 除了使用typeof返回的类型不同以外,包装对象与基本值类型另外一个不同在于:
使用包装对象可以为其添加新的属性和方法,但是基本值类型不同
var str="hello world"; str.smile=true; console.log(str.smile);//undefined var string=new String("hello world"); string.smile=true; console.log(string.smile);//true
5 在使用包装对象的时候,如果不使用new操作符,那么相当于基本值类型,不再是包装对象
八错误对象
1 JS中有一些内置错误构造函数,例如Error(),SyntaxError(),TypeError,RangeError等,这些错误构造函数都带有throw语句
2 这些对象的实例拥有下面一系列的属性:name:构造函数的名称属性;message:创建对象时传递给构造函数的字符串
3 throw适用于任何对象,并不一定是由某个错误构造函数所创建的对象,因此,我们可以使用throw抛出自己的对象,然后传递给catch处理
try{
throw{
name:"q",
message:"ww",
rowNum:"2"
};
}catch(e){
console.log(e.rowNum);//2
}
try{
throw new Error("Oops,出错了");
}catch(e){
console.log(e.message);//Oops,出错了
}
九 小结
1 对象字面量表示法是一种优美的创建对象的方式,以大括号包装,以逗号分隔的键值对
2 确保自定义的构造函数表现的如同使用new运算符的方法
3 JSON