zhuhuiwen Front-end Dev Engineer

js面向对象第二天

2016-11-26

11/26/2016 8:54:22 AM

面向对象编程的举例

  1. 设置div和p的border: 1px solid red
    1. 快捷键itar
    2. 分析需求–>步骤–>写代码
  2. 函数 重要点: 返回值 参数 函数名
  3. 使用函数封装存在的问题
    1. 全局变量污染
    2. 代码结构混乱,维护不便
  4. 解决上面存在的问题(对象封装)
    1. 命名空间
      1. 在其他元 c= c++ java
      2. 就是限定变量访问方式的一个范围
      3. 解决方式
      4. 在js中
        1. var zhuhw={} 只能通过zhuhw. 进行范文里面的内容
        2. zhuhw{tag:function(){},setBorder:funtion{}}
        3. 全局变量污染解决
    2. 解决混乱
      1. getEle{tag:function(){}}
      2. setStyle{setBorder:function(){}}
      3. 解决混乱
      4. 动画模块
      5. 事件模块
  5. 使用方式:
    1. 命名空间.模块.方法
  6. 面向对象编程的优势
    1. 避免了全局变量污染
    2. 将代码进行了模块划分,结果清晰,便于维护 11/26/2016 9:25:32 AM

创建对象的方式

  1. 字面量
    1. {}
      1. 存在的问题
        1. 代码复用性太差,每次创建的对象都需要手动的所有成员
  2. 使用内置构造函数
    1. var p = new Object();
    2. 自己添加属性 p.name =’’;
    3. 使用内置构造函数创建对象,创建出来的都是空对象,
    4. 需要手动的去添加属性和方法
    5. 复用性不好

创建对象的方式(自定义构造函数)

构造函数

  1. 构造函数是一个函数,一般用来初始化对象
  2. 特点:
    1. 首字母大写
    2. 一般和new关键字一起使用
    3. 不需要手动书写return语句,会默认的返回创建粗来的对象
  3. 创建一个人
  4. 构造函数的执行过程
    1. 首先使用new关键字来创建对象
    2. 调用构造函数,将构造函数的ths赋值为new 创建出来的对象
    3. 在构造函数内部使用this为新创建女出来的对象新增成员(初始化过程)
    4. 默认的返回刚才创建的对象
  5. 返回值的注意事项
    1. 如果手动写return语句
      1. 如果返回的是值类型的数据,则对原来的返回值,没有影响
        1. null 这边是简单类型,没影响
      2. 如果返回的是引用类型的数据,则替换原来的返回值
  6. 传参数就可以改变值

扩展:构造函数能不能像正常函数使用

  1. 普通的函数,直接是window调用
  2. 构造函数
    1. 可以调用,但是构造函数的this,会指向window对象

传统构造函数存在的问题

  1. 写一个函数用来创建dog对象
  2. Dog
    1. 属性: type gender
    2. 方法: bark
  3. 新建一个对象
    1. 函数执行完成后被回收
    2. 引用类型比较的时候是比较的地址
  4. 如果在构造函数内部创建函数,并且给对象新增方法,哪儿通过构造函数创建出来对象,每个对象都会独占一份,所以造成资源浪费

解决函数问题

  1. 解决方案
    1. 在构造函数创建指定函数
    2. 在构造函数内部为对象新增方法的时候,不徐娅在创建函数,而是直接用在外部创建好的函数的地址 2 存在的问题
    3. 胡造成全局变量污染
    4. 代码结构右混乱了

原型

1. 原型 1. 在构造函数创建出来的时候,系统会默认的帮这个构造函数创建并且关联一个空对象

  1. 原型的访问方式
    1. 构造函数.prototype
    2. 打印一个对象
  2. 原型的作用
    1. 所有成员都可以被
  3. 补充的一些小概念
    1. 实例
      1. 通过供函数创建出来的对象,可以成为该构造函数的一个实例
      2. 实例化
        1. 通过构造函数来
  4. 使用原型解决构造函数存在的问题 1. 将方法的定义放在原型中,所有的对象都可以取共享该方法了,也不会造成资源的浪费

  5. 作用
    1. 可以
  6. 回答
    1. 构造函数的属性
    2. 注意区分构造函数的属性
    3. 和对象的属性

原型的使用

  1. 利用对象的动态特性为原型添加成员
  2. 直接替换了原型对象
    1. 直接个一个新的对象进行替换
    2. 系统自己的还有吗?? 多出来的???

原型的使用注意事项

  1. 使用对象.属性名去获取对象属性的时候,会现在自己种进行查找,如果没有,就去原型
  2. 如果设置对象属性的时候,只会在在吱声查找,如果有就修改,如果没有就添加
    1. 是复制一份吗???属性
  3. 一半请下,不会讲属性防放在原型当中,只会将方法放在原型中

  4. 直接Person.prototype{}
  5. 解释怎么存储的
    1. 画图
  6. 在替换原型的时候,替换之前替换的对象,和替换只会的对象那个的原型不一致
  7. 对象关联的原型就是创建对象那一刻,构造函数的prototype属性
    1. 在创建一个对象,可以访问最后一次创建的吗???
  8. 访问—先自己 再原型
  9. 设置 – 自己没有,设置;有,替换
  10. 公用的放在原型,独有的自己
  11. 替换之前对象,替换之后的对象,原型吧托尼盖
  12. 对象关联的
    1. 最后一个得到的
  13. 中间 写代码 画图

proto

  1. proto
    1. 是一个非标砖的属性,最早由火狐提出来,一半情况下,不推荐使用该属性来操作原型对象
      1. 因为不是标准的,有可能出现不兼容
      2. 稳定性问题
        1. 保证一致性
      3. 什么时候使用
        1. 只在调试的时候使用…
  2. 一半情况下
    1. ————开头的属性都是非标准的属性
    2. ——单下划线的属性,私有的属性(只是在自己用,不推荐在外面用)
  3. 构造函数名.prototype(推荐使用)
  4. 对象名.proto (一般调试)

11/26/2016 11:39:09 AM 11/26/2016 1:44:10 PM js事件万物诞生记

09———————-

  1. 疑问
    1. 变量设置 是直接在自己里面设置
    2. 创建了2个,创建了两个对象 后面又写了一次… 第二个 还是 最新的… 原因是在创建的时候进行有对象的

11/26/2016 2:40:53 PM

继承再看

  1. 混入时继承
  2. 原型继承:
    1. 使用原型实现的继承就是原型继承
  3. 方式
    1. 通过修改原型队形实现继承
      1. 利用混入的方式,为原型对象添加对象
        1. Person创建出来的而对想都是继承hu的
    2. 通过替换原型对象实现继承
      1. Person.prototype = hu;
        1. 直接human给person的原型不行吗????
  4. 扩展
    1. 赋值额继承距离
    2. 继承时基于对象的 先创建一个对象在 Human.proto = ani; 注意
    3. 灰色的 构造函数的名称
    4. Animal解释
  5. 原型的const属性
    1. 原型对象那个中有一个属性. constructor
    2. 这个属性就执行那个跟该原型对象相关的构造函数
      1. 当创建出来构造函数—原型 (同时创建出来的)
      2. 在替换原型对象智慧和,constructor属性会丢失
        1. 自己指回来,没变之前的线还在吗?????——————–???construction有多根线
  6. 原型
    1. 给其添加一个属性,
      1. 取值的时候,先函数再原型 ——是的
      2. 赋值的时候,函数自己有就是替换
        1. 原型有呢? 会是复制出来一份替换吗?(给自己—-不出现复制出来一份,因为本来就是自己的,有就改,没有就添加进去)
          1. —–不会去原型里面找,这个是规定
  7. 原型的那根线
    1. prototy— 只有一个指向 ——-是的
    2. constructor—各是各的???——是的

——————–完成

11/26/2016 3:36:18 PM

原型链

  1. 每个对象都有原型对象,原型对象也是一个对象,所以原型对象也有原型对象,这样就形成了一个链式的结构,这个链式结构就称为原型链
  2. 分析
    1. p–>Person.prottype–>Obj.prottype—>null
    2. function Person(){} var p = new Person();
  3. 原型链练习
    1. arr–>Array–>Obj—>null
      1. [] 特殊点
    2. date —>Data.p—>Obj. —>null
    3. reg —>RegExp.p—>Obj. —>null
    4. 会说
      1. 最后一环都是obj

属性搜索原则

  1. 在使用对象进行属性获取的时候,会准准一下的属性搜索原则
    1. 现在对象本身中查找,如果找到了就直接使用
    2. 如果没有找到,就去对象的原型对象中参照,如果找到
    3. 如果没有找到,就去原行政进行找….
    4. 如果没有找到,就沿着
  2. 注意
    1. 设置属性的时候,不会使用属性搜索原则
      1. 只看自己
  3. 例子

    继承的作用

  4. 当前的用的最多的—面试
  5. 继承应用举例
    1. 注意
      1. 不能直接修改系统的内置对象
      2. 因为内置对象被所有人共享,如果所有人都去修改内置对象
      3. 那么会造成不确定性
  6. 如何安全的扩展内置对象
    1. 写一个构造函数
    2. 将Arr一个对象给他
    3. 完了之后就是一个新的,自己改不会影响内置对象
  7. array实例的 本是没有的,就自己再去找自己的原型—画图出来的
  8. 注意
    1. String的不可以通过自己创建…,只能通过修改包装类型
  9. trim
    1. 给string扩展方法

instanceof

  1. 作用
    1. 判断一个对象是不是某个构造函数的实例(不够精确)
    2. 解决办法
      1. 判断一个构造函数的原型是不是在该对象的原型链上
      2. 例子
        1. p–>Person.pro—>Obj.pro—>null

Obj.pro的成员介绍

  1. 监视
    1. console.log显示不可靠
    2. 在watch看对象的属性和方法
  2. 属性
    1. constructor属性
      1. 指向和原型相关的构造函数
    2. hasOwnProperty方法
      1. 判断一个对象自身是否有的属性
      2. 返回值有或者没有,是一个布尔值(原型中的属性不是自身的属性)
      3. in关键字操不管你是原型里的还是自身的,只要有就是true
    3. isPrototypeOf 方法
      1. 对象名.isPrototypeOf(对象1)
      2. 功能
        1. 判断对象是不是对象1的原型对象
    4. propertyIsEnumerable方法
      1. 对行吗.propertyIsEnumerable(属性名)
      2. 功能:
        1. 判断对象本身中是否拥有某个属性(原型中的不算) 并且
        2. 判断对象的指定的属性讷讷个否被遍历(for-in)到
    5. toLocalString toString 1. 功能一样的地方 1. 都是讲对象转换成字符串 2. toLocalString 1. 会将对象以本地格式打印出来(计算机本身) 3. toString 1. 会直接将对象以字符串的格式打印,跟本地格式无关
    6. valueOf
      1. 获取对象的值
      2. 功能
        1. 当对象类型和值类型参与运算的时候
        2. 1
      3. 一个小例子
    7. __proto__对象
      1. 指向对象的原型对象 11/26/2016 5:22:55 PM

js高级第二天

面向对象举例

创建对象的方式

原型

继承

原型链

Object.prototype的成员

11/26/2016 6:46:55 PM

复习

面向对象编程的举例

  1. 直接进行写函数的方式
    1. 代码复用性太低
  2. 函数封装
    1. 进行封装两个行数
    2. 使用函数封装存在的问题:
      1. 全局污染,使用命名空间
      2. function在全局的会出现 全局污染 和 混乱不方便管理
  3. 面向对象编程的优势
    1. 优势
      1. 命名空间 :避免了全局变量污染
      2. 函数分模块模块:将代码进行了模块的划分,结构清晰,便于维护
    2. 代码

       //设置命名空间show
         var show = {
               //继续讲属性进行设置模块化,解决的问题是不方便管理
               //获取元素的模块
               getEle : {
                   tag: function(tagName){
                       return document.getElementsByTagName(tagName);
                   }
               },
               //设置元素的样式模块
               setStyle:{
                   setBorder:function(tags){
                       for(var i=0;i<tags.length;i++){
                           tags[i].style.border = '1px solid red';
                       };
                   }
               }
           };
           var divs = show.getEle.tag('div');
           show.setStyle.setBorder(divs);
      

创建对象的方式

  1. 字面量{}
    1. 代码复用性太差,每次进行创建的对象都需要手动的添加所有的成员对象
    2. 代码

       var p1 = {
           name:'wa',
           sayP1:function(){
               console.log('---p1---');
           }
       };
      
  2. 内置构造函数 new的方式
    1. 创建出来的对象都是空对象,属性和方法需要自己添加
    2. 代码

       var p3 = new Object();
       p3.name = 'qg';
       p3.sayHi = function(){
           console.log('----p3-----');
       };
       p3.sayHi();//----p3-----
      
  3. 自定义构造函数

构造函数

  1. 概念
    1. 构造函数是一个函数,一般用来初始化对象
  2. 构造函数的特点
    1. 首字母大写
    2. 一般和new关键字一起使用
    3. 不需要手动书写return语句,会默认的返回创建出来的对象
  3. Person构造
    1. 代码

       /*Person构造*/
       function Person(name){
           this.name = name;
           this.say = function(){
               console.log(name+'----say');
           };
           // return null; 值类型,没有任何影响
          /* return {
               name:'kaguo'
           };
           是复杂数据类型,就返回了一个return回去的对象
           6.自定义构造函数.html:29 Uncaught TypeError: p1.say is not a function(…)
           */
       }
       var p1 = new Person('wa');//wa----say
       	p1.say();
      
  4. 构造函数的执行过程
    1. 首先使用new关键字来创建对象
    2. 调用构造函数,将构造函数内的this赋值为new创建出来的对象
    3. 在构造函数内部使用this为新创建出来的对象新增成员(初始化过程)
    4. 默认的返回刚才创建出来的对象
  5. 返回值的注意事项
    1. 如果手动写return语句,
      1. 如果返回的是值类型的数据,则对原来的返回值,没有任何影响(包括null)
      2. 如果返回的是引用类型的数据,则替换原来的返回值
    2. 代码

       function test(){
       this.name = 'kag';
       	console.log(this);
      	 }
         		 test();//返回的是一个window对象
      

传统的构造函数存在的问题

  1. 解释
    1. 如果在构造函数内部创建函数,并且给对象新增方法,
    2. 那么通过构造函数创建出来的对象,每个对象都会独占一个方法
    3. 所以会造成资源浪费
  2. 代码

     /*写一个dog对象*/
     function Dog(name){
         this.name = name;
         this.bark = function(){
             console.log(name+'wang');
         }
     }
     var dog1 = new Dog('hh1');
     dog1.bark();//wang
     var dog2 = new Dog('hh2');
     dog2.bark();
    
     //比较两个对象调用的bark是不是同一个function
     console.log(dog1.bark==dog2.bark);//false
    
  3. 补充
    1. 代码

       注意: 对象比较的是地址,两个function和下面的{}对象存在两个不同的地址上
        	console.log(function(){}==function(){});//false
       console.log({}=={});//false
      

解决普通构造函数问题方法一

  1. 在构造函数外部创建指定函数
  2. 在构造函数内部为对象新增方法的时候,不需要再创建函数,而是直接用在外部创建好的函数的地址
  3. 代码
    1. 写一个构造函数,用来创建狗对象
    2. 将函数放置在构造函数外部
    3. 代码

       /*
       * 存在的问题:
       * 1.会造成全局变量污染
       * 2.代码结构又混乱了
       * */
       function bark(){
       console.log('wang');
       }
       function Dog(name){
           this.name = name;
           this.bark = bark;
       }
       var dog1 = new Dog();
       dog1.bark();//wang
       var dog2 = new Dog();
       dog2.bark();//wang
       console.log(dog1.bark===dog2.bark);//true ## 原型的基本概念 ##
      
  4. 在构造函数创建出来的时候,系统会默认的帮这个构造函数创建并且关联一个空的对象,这个对象就是原型
  5. 原型的访问方式
    1. 构造函数名.prototype
  6. 原型的作用
    1. 构造函数的原型中的所有成员,都可以被该构造函数创建出来的对象访问(共享)
  7. 补充的一些小概念
    1. 实例:通过构造函数创建出来的对象,可以称为该构造函数的一个实例
    2. 实例化:通过构造函数来创建对象的过程,就是实例化
  8. 使用原型解决构造函数存在的问题
    1. 将方法的定义放在原型中,所有的对象就都可以去共享该方法了,也就不会出现资源浪费的情况
  9. 代码

     function Person(name){
         this.name = name;
     }
     Person.prototype.sayHi = function(){
         console.log('---打印中---');
     }
     var p1  = new Person();
     p1.sayHi();//---打印中---
     var p2  = new Person();
     p2.sayHi();//---打印中---
     console.log(p1.sayHi==p2.sayHi);//true
    

原型的使用方式

  1. 利用对象的动态特性为原型添加成员
  2. 替换原型对象
  3. 代码

     function Person(){
         this.name = "";
         this.gender = "";
         this.age = 0;
     };
     Person.prototype.sayHi = function(){
         console.log('利用对象的动态特性为原型添加成员');
     }
     var p1 = new Person();
     //在watch中打印出来Person的原型被改变了
     Person.prototype = {
         sayHello:function(){
             console.log('替换原型对象');
         }
     };
     var p2 = new Person();
     p2.sayHello();//替换原型对象
     //因为被替换掉了
     p2.sayHi();//Uncaught TypeError: p2.sayHi is not a function(…)
    

原型的使用注意事项

  1. 对象.属性名 获取和设置属性
    1. 使用对象.属性名去获取对象属性的时候
      1. 会先在自身中进行查找,如果没有,就去原型中查找
    2. 使用对象.属性名去设置对象属性的时候,
      1. 只会在自身进行查找,如果有,就修改,如果没有,就添加
      2. 不会去原型中去找,自己有就修改,没有就添加
  2. 代码案例

        function Person(){
        }
        Person.prototype.name = "张三丰";
        var p = new Person();
        console.log(p.name);//张三丰
        p.name = "张四风";//这边是赋值操作,不会去找原型
        console.log(p.name);//张四风
        var p1 = new Person();
        console.log(p1.name);//张三丰
    
  3. 替换原型
    1. 在替换原型的时候,替换之前创建的对象,和替换之后创建的对象的原型不一致!!!
    2. 对象关联的原型,就是创建对象那一刻,构造函数的prototype属性
  4. 代码案例

         function Person(){
        }
        Person.prototype = {
            sayHello:function () {
                console.log("Nice to meet you");
            }
        }
        var p = new Person();
        // p.sayHello();//Nice to meet you
    	
        Person.prototype = {
            sayHi:function () {
                console.log("Sad to meet you");
            }
        }
        var p1 = new Person();
        //p1.sayHello(); //p1.sayHello is not a function(…) 报错
        p1.sayHi();//Sad to meet you
        p.sayHi();//11-原型的使用注意事项.html:40 Uncaught TypeError: p.sayHi is not a function(…)
        p.sayHello();////Nice to meet you
        console.log(p1.__proto__ === Person.prototype);//true
        console.log(p.__proto__);//prototype:sayHello
    

访问原型的方式的第二种方式__proto__

  1. proto
    1. 是一个非标准的属性,最早由firefox提出来
    2. 一般情况下 ,不推荐使用该属性来直接操作原型对象
      1. 由于兼容性问题,不推荐使用
      2. 由于稳定性问题,不推荐使用
    3. 只在调试的时候使用。。
  2. 访问原型的方式
    1. 构造函数名.prototype
    2. 对象名.proto
  3. 一般情况下
    1. __开头的属性都是非标准的属性
    2. _开头的属性,私有的属性
  4. 代码

         function Person(){
         };
         console.log(Person.prototype);//Object {}
         var p = new Person();
         console.log(p.__proto__);//Object {}  p的原型是一个空的对象
         console.log(Person.prototype==p.__proto__);//true
    

继承再探

  1. js中继承的方式
    1. 混入式继承
    2. 原型继承 使用原型实现的继承就是原型继承
      1. 通过修改原型对象实现继承
        1. 利用混入的方式,为原型对象添加成员
      2. 通过替换原型对象实现继承
  2. 混入式继承代码

         混入式继承
         var obj1 = {
             name :'waxun',
             age:'11'
         };
         var obj2 = {};
         for(var k in obj1){
             obj2[k] = obj1[k];
         }
         //Object {name: "waxun", age: "11"}
         console.log(obj2);//可以继承到obj1中的值
    
  3. 原型继承 使用原型实现的继承就是原型继承

     function Hum(){
         this.name = 'waxun',
         this.age = 11
     }
     function Person(){};
     //利用混入的方式,为原型对象添加成员
     var h = new Hum();
     for(var k in h){
         Person.prototype[k] = h[k];
     };
     var p1 = new Person();
     /!*
     在console中打印p1中的原型,成功的继承了
      p1.__proto__
     Object {name: "waxun", age: 11}
     *!/
     console.log(p1.name);//waxun
     var p2 = new Person();
     console.log(p2.name);//waxun
    
  4. 通过替换原型对象实现继承

      function Hum(){
         this.name = 'waxun',
                 this.age = 11
     }
     function Person(){};
     var h = new Hum();
     //继承是根据对象来说的,直接将h中拥有的属性都给了Person构造函数的原型了
     Person.prototype = h;
     var p1 = new Person();
     console.log(p1.name);//waxun
    
     代码检验
    
     p1.__proto__
    	Hum {name: "waxun", age: 11}
    

复杂的继承举例(不要求掌握)

  1. 代码案例

     <script>
         function Animal(){
             this.age = 10;
             this.gender = 'male';
         };
         //因为是通过对象的方式进行将属性什么的赋值给子对象的
         var ai = new Animal();
    	
         function Human(){
             this.IQ = 180;
             this.name = "";
         };
         Human.prototype = ai;
         var huma = new Human();
         console.log(Human.prototype);
         //因为一级一级的向上找到Animal,constructor就还是指向的是Animal,将改回自己的构造函数
         Human.prototype.constructor = Human;
         console.log(Human.prototype.constructor);
     </script>
    

原型对象中有一个属性 .constructor

  1. 原型对象中有一个属性 .constructor
  2. 这个属性就指向跟该原型对象相关的构造函数
  3. 在替换原型对象之后,constructor属性会丢失
  4. 代码案例

    function Person(){};
    console.log(Person.prototype);//Object {}
    //function Person(){}  指向的是该原型对象相关的构造函数
    console.log(Person.prototype.constructor);
    
    Person.prototype = {
        name:'waxun'
    };
    console.log(Person.prototype.constructor);//function Object() { [native code] }
    //将其进行指回来
    Person.prototype.constructor = Person;
    console.log(Person.prototype.constructor);
    
    </script>
    

原型链

  1. 原型链
    1. 每个对象都有原型对象,原型对象也是一个对象,所以呢原型对象也有原型对象
    2. 这样就形成了一个链式的结构,这个链式结构就称为 原型链
  2. 代码

     function Person(){};
     var p = new Person();
     //p-->Person.prototype-->Object.prototype-->null
     console.log(Person.prototype);//Object {}
    

原型链练习

  1. js中的内置对象的原型
  2. 在当前环境下浏览器进行看的数据
  3. 代码

         /*
         * 在当前环境下浏览器进行看的数据
         * arr.__proto__
          []
          arr.__proto__.__proto__
          Object {}
          arr.__proto__.__proto__.__proto__
          null
    	
    	
         * */
         //arr-->Array.prototype-->Object.prototype-->null
         var arr = new Array();
    	
        /* date
          Sun Nov 27 2016 00:45:36 GMT+0800 (中国标准时间)
          date.__proto__
          Object {}constructor: Date()getDate: getDate()getDay: getDay()getFullYear: getFullYear()getHours: getHours()getMilliseconds: getMilliseconds()getMinutes: getMinutes()getMonth: getMonth()getSeconds: getSeconds()getTime: getTime()getTimezoneOffset: getTimezoneOffset()getUTCDate: getUTCDate()getUTCDay: getUTCDay()getUTCFullYear: getUTCFullYear()getUTCHours: getUTCHours()getUTCMilliseconds: getUTCMilliseconds()getUTCMinutes: getUTCMinutes()getUTCMonth: getUTCMonth()getUTCSeconds: getUTCSeconds()getYear: getYear()setDate: setDate()setFullYear: setFullYear()setHours: setHours()setMilliseconds: setMilliseconds()setMinutes: setMinutes()setMonth: setMonth()setSeconds: setSeconds()setTime: setTime()setUTCDate: setUTCDate()setUTCFullYear: setUTCFullYear()setUTCHours: setUTCHours()setUTCMilliseconds: setUTCMilliseconds()setUTCMinutes: setUTCMinutes()setUTCMonth: setUTCMonth()setUTCSeconds: setUTCSeconds()setYear: setYear()toDateString: toDateString()toGMTString: toUTCString()toISOString: toISOString()toJSON: toJSON()toLocaleDateString: toLocaleDateString()toLocaleString: toLocaleString()toLocaleTimeString: toLocaleTimeString()toString: toString()toTimeString: toTimeString()toUTCString: toUTCString()valueOf: valueOf()Symbol(Symbol.toPrimitive): [Symbol.toPrimitive]()__proto__: Object
          date.__proto__.__proto__
          Object {}__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: __proto__()set __proto__: __proto__()
          date.__proto__.__proto__.__proto__
          null*/
    	
         //date -->Date.prototype-->Object.prototype-->null
         var date = new Date();
    	
         /*reg
          /(?:)/
          reg.__proto__
          Object {}
          reg.__proto__.__proto__
          Object {}
          reg.__proto__.__proto__.__proto__
          null*/
         reg-->RegExp.prototype-->Object.prototype-->null
         var reg = new RegExp();
    

属性搜索原则

  1. 在使用对象进行属性获取的时候,会遵循以下的属性搜索原则
    1. 现在对象本身中进行查找,如果找到了就直接使用
    2. 如果没有找到,就去对象的原型对象中查找,如果找到了就直接使用
    3. 如果没有找到,就去原型对象的原型对象中进行查找,如果找到了就直接使用
    4. 如果没有找到,就沿着原型链继续往上查找,只到找到null为止
  2. 注意:
    1. 设置属性的时候,不会使用属性搜索原则
  3. 代码案例

     function Person(){};
     Person.prototype.car ={
         type:"Ferrari",
         model:"430"
     };
     var p = new Person();
     console.log(p.car);//Object {type: "Ferrari", model: "430"}
     console.log(p.car===Person.prototype.car);//true
     // var car = p.car;
     //所以car对象和p的原型链中的car对象指的是同一个
     //  car.type="布加迪";
     p.car.type = "布加迪";
     var p1 = new Person();
     console.log(p1.car.type);//布加迪
    

继承应用继续举例

  1. 不能直接修改系统的内置对象
    1. 因为内置对象被所有人共享,如果所有人都去修改内置对象,那么会造成好多的不确定因素
  2. 代码案例

         var arr = new Array();
         Array.prototype.sayHi = function(){
             console.log('1');
         }
         Array.prototype.sayHi = function(){
             console.log('2');
         }
         Array.prototype.sayHi = function(){
             console.log('3');
         };
         arr.sayHi();//3
    
  3. 如何安全的扩展内置对象
    1. 新建一个对象
    2. 创建一个数组的对象的实例,
    3. 将这个实例所拥有的东西给新建对象的prototype
    4. 这个新对象就拥有了一系列属性和方法
  4. 代码案例

     function MyArray(){};
     var arrTemp = new Array();
     MyArray.prototype = arrTemp;
     MyArray.prototype.sayHi = function(){
         console.log('我自己的拉');
     }
     var arr1 = new MyArray();
     arr1.sayHi();//我自己的拉
     arr1.push(1);
     console.log(arr1);//[1]
    

instanceof

  1. 判断一个对象是不是某个构造函数的实例 (不够精确)
  2. 准确的说法是:
    1. 判断一个构造函数的原型是不是在该对象的原型链上
  3. 代码

          //p---->Person.prototype----->Object.prototype---->null
         function Person(){};
         var p = new Person();
         console.log(p instanceof  Person);//true
         console.log(p instanceof  Object);//true
        // console.log(p instanceof  null);//Right-hand side of 'instanceof' is not an object(…)
    

Object.prototype的成员介绍

	   /*
	    * 1. constructor属性
	    *   指向和原型相关的构造函数
	    * 2. hasOwnProperty 方法
	    *   判断对象自身是否拥有某个属性(原型中的属性不是自身的属性)
	    *   返回值表示有或没有 是一个布尔值
	    *   注意
	    *      in关键字才不管你是原型里的还是自身的  只要有  就是true
	    *3.isPrototypeOf 方法
	    *   对象名.isPrototypeOf(对象1)
	    *   功能:判断对象是不是对象1的原型对象
	    *4.propertyIsEnumerable 方法
	    *   对象名.propertyIsEnumerable(属性名)
	    *   功能:
	    *       1.判断对象本身中是否拥有某个属性  并且
	    *       2.判断对象的指定的属性能否被遍历(for-in)到
	    *5.toLocaleString  toString
	    *   功能一样的地方:都是将对象转换成字符串
	    *   toLocaleString 会将对象以本地格式打印出来   (本地格式取决于计算机的设置)
	    *   toString 会直接将对象以字符串的格式打印,跟本地格式无关
	    *6.valueOf
	    *   获取对象的值
	    *   功能,当对象类型和值类型参与运算的时候
	    *   会首先的调用对象的valueOf方法,如果返回的值可以参与运算,就直接使用
	    *   如果不能参与运算。则需要调用toString方法,获得结果之后再去运算
	    *7.__proto__属性
	    *   指向对象的原型对象
	    *
	    *
	    *
	    * */ 11/27/2016 1:23:07 AM 

Similar Posts

Comments