博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一 对象字面量

  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