JS的对象和原型;

    天天在讲对象,写了一年的JS代码了,在实际的业务开发中(大厂的当我没说),不使用框架,对象和原型继承用到的还是非常多的,例如某一个方法在多个对象实例中都会用到,那么这个时候我们写原生的JS,封装方法,实现子类继承是非常有必要的,如果你不这么干,那么可以收拾收拾桌上的东西,回家了!

    从哪儿开始说呢?我想了一会儿,决定从对象开始说;

    什么是对象?

    《JavaScript高级程序设计》是这么说的:对象是若干个(无序的)属性的集合,属性是可以包含基本类型数据和(引用类型数据)复合类型数据的标识符;

    什么是属性?

    上面那句话已经说了,看代码你就能深刻认识属性;  

1 name:'振振';     我没有在外层给他一个挂载的对象,但是一个属性拿出来就是这个样子,就是key:value,左边是键名,右边是值,通过JS的点表示法,可以从对象上访问到这个键名叫做name的属性,他返回一个字符串,就是你写的这个字符串字面量;对,没错,这就是属性,很简单,你也可以理解成是变量,他保存了一个字符串‘振振’的字符,在变量name中;都没有问题,只要你能理解他,他就是对的;

    【属性里能保存那些东西?】

    可以保存:基本数据,和对象(数组、函数本质上都是对象);

    基本数据是啥?

    JS中一共有几种基本数据类型?你问我?

    引用类型是啥?

    去看我这篇博客,你就知道啥是引用类型:http://www.cnblogs.com/wukong-js/articles/7424465.html

    【属性的分类】

    对,没错,属性有分类,这个分类上面说的是属性可以保存的数据类型,这里说的是属性的分类,不是一个东西,要分清,不要弄混了;

    有两个:1.数据属性 2.访问器属性

    【属性的特性】

    属性的特性是JS这门语言比较特别的地方,特别在哪儿呢?JS可以让你精确的控制对象的属性是否可读、可写、可枚举、可配置;{牢记这四点属性的特性;}

    数据属性的特性:

      直接上代码:

      

1 2 3 4 5 6 7 8 9 10 var obj = { name:'振振' };

obj.defineProperty(obj,'name',function(){ configurable:true/false, enumerable:true/false, writable:true/false, value:'振振的副本' });     这段代码很简单,啥意思呢?

    先说四个特性的意思:可读就是能不能通过点表示法来获得这个属性的值,可写就是能不能在定义以后修改这个属性的值,可枚举就是能不能被循环遍历出来,可配置就是属性的特性定义以后还能不能第二次配置这些可读可写可枚举啥的;

    上面代码我声明了一个对象叫做obj,然后给了这个对象一个属性,叫做name,它的值是一个字符串;

    如果你想修改对象的属性的特性需要使用JS给对象内置的一个方法叫做defineProperty()函数,他是Object上的一个方法,就像toString一样,原生自带的,所有对象都有这个方法,所以,调用的时候直接使用点表示法,调用即可;(解释一下这个点表示法是啥意思:你可以用语文中“的”这个字来代替点,例如obj对象-的-defineProperty方法,就是这么个意思;);

    【defineProperty方法参数】

    这个方法接受三个参数,第一个参数是,你要修改的--[对象的属性]--的特性--的对象,(怕你们不会断句,我帮你断好了),

               第二个参数是,你要修改的属性名;

             第三个参数是,一个回调函数;

     具体设置项的意思:

      configurable:是否可配置;

      enumerable:是否可读;

      wriable:是否可写;

      value:属性的值;

     好了,数据属性的特性就讲完了,这就是用法;之于兼容性,IE8及以下有问题,什么问题我就不说了,如果你们公司还兼容IE9及以下的话,离职吧,你别干了;

    

    访问器属性的特性:

      还是先看代码:

      

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var obj = { _age:20, get:function(){ return this._age; }, set:function(value){ this._age = value; } } obj.age;//20; obj.age = 30; obj.age;//30; obj._age;//30;

//或者你可以使用defineProperty()函数来设置访问器属性的特性   访问器属性一样是有四个特性:可读,可写,可枚举,可配置;

  这个比数据属性的特性的可读可写药灵活一些,因为我们可以通过get访问器来精确控制别人访问这个属性的时候,我给你什么值;之于这个 _age是什么意思,一般加个下划线的意思是,告诉别人我这是私有属性,你不要直接访问,或者是你可以直接将所有的私有属性设置为不可枚举,这样就更像是私有属性;

  【在set和get访问器这里有一个知识点比较重要,但是我想到了,突然提笔忘字,忘了,唉,等我想起来在补上吧!】

  【一般只有在设计框架或者是JS类库的时候才会用到这些知识,平时开发,写业务,是用不到这些东西的,这个暂时知道一下,或者你可以去读一读《你不知道的JavaScript》然后尝试着设计并实现一个MVC的框架】

  

   【创建对象】

   讲了好一会儿对象的属性,让我们一起创建一个对象吧;Object;

   创建对象的几种方式:

  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 /对象直接量,这种方式是最简单直观的,比较常用的/ var obj = { name:'振振' }

/使用new操作符合Object()函数创建对象/ /Object对象是JS中最大的最顶层的那个对象,换句话说,JS中任何一个对象都是由构造函数的方式创建的对象/ var obj = new Object(); /new操作符后面你可以跟任何的函数,构造函数就是普通的函数/

/构造函数创建对象,这种方式用的也非常多,在模拟其他语言的类的继承的时候,都会选用构造函数加原型的混合模式来创建对象/

function Person(name,age){ this.name = name; this.age = age; this.getName = function(){ return this.name; } } var obj = new Person('振振',20);

/实际上,上面的对象直接量是这样的:var obj = new Object();/

/还有一种是工厂模式,其实这种我不想说的,因为我觉得不会有人再用这个方式创建对象了/ function createObj(name,age){ var obj = {}; obj.name = name; obj.age = age; obj.getName = function(){ return this.name; } } var ren = createObj('振振',20); 上面说了那么多,其实最常用的就是对象直接量和构造函数,这两种方式创建对象;

new了一个对象之后,通过这个对象名然后点表示法跟一个属性名是啥意思?

意思是,如果这个对象上有这个属性,则修改属性,前提是属性可写的,如果没有,则在这个对象上创建一个你点上的这个属性,就是:obj.name,在obj这个对象上创建了一个name属性,如果有name属性就修改name属性;

【函数中的this】

this是什么?它充当了指针的作用,它始终指向当前对象,它代表着当前对象,指向所处环境的上一级,如果上一级没有,就是执行宿主对象,就是Global对象,虽然我们无法访问到Global对象,但是在宿主环境中,也就是客户端中的宿主环境中的Glogal对象就是window对象,那么this就指向window;

一句总结的比较经典的解释this指向谁:谁调用的就指向谁;

看个代码,来理解这个谁调用就是谁!

1 2 3 4 5 6 7 var o = { name:'haha', getName:function(){ return this.name; } } console.log(o.getName());//haha   我创建了一个对象o,然后给这个对象添加了两个属性,一个属性是基本类型数据,还有一个是引用类型数据,换成人话就是,一个属性存了一个字符串,另一个属性存的是一个地址,是一个指向堆中保存函数方法的存储空间,(如果你不明白,去看我的《ES5中的值传递/引用传递》这篇博客;)这个函数执行一个操作,它将给我们返回一个当前对象的name属性的值;

这个时候是谁调用的它,是getName函数吗?不是,是o对象调用了getName方法,而这个方法中的this就是o对象,如果这条return语句这么写你就明白了:return o.name;

返回o对象的name属性;

/天晚了,先说到这里,明天再说原型/