- 面向对象编程的举例
- 创建对象的方式
- 创建对象的方式(自定义构造函数)
- 解决函数问题
- 原型
- 原型的使用
- 原型的使用注意事项
- proto
- 继承再看
- 原型链
- 属性搜索原则
- 继承的作用
- instanceof
- Obj.pro的成员介绍
- js高级第二天
- 面向对象举例
- 创建对象的方式
- 原型
- 继承
- 原型链
- Object.prototype的成员
- 复习
- 面向对象编程的举例
- 创建对象的方式
- 传统的构造函数存在的问题
- 解决普通构造函数问题方法一
- 原型的使用方式
- 原型的使用注意事项
- 访问原型的方式的第二种方式__proto__
- 继承再探
- 复杂的继承举例(不要求掌握)
- 原型对象中有一个属性 .constructor
- 原型链
- 原型链练习
- 属性搜索原则
- 继承应用继续举例
- instanceof
- Object.prototype的成员介绍
11/26/2016 8:54:22 AM
面向对象编程的举例
- 设置div和p的border: 1px solid red
- 快捷键itar
- 分析需求–>步骤–>写代码
- 函数 重要点: 返回值 参数 函数名
- 使用函数封装存在的问题
- 全局变量污染
- 代码结构混乱,维护不便
- 解决上面存在的问题(对象封装)
- 命名空间
- 在其他元 c= c++ java
- 就是限定变量访问方式的一个范围
- 解决方式
- 在js中
- var zhuhw={} 只能通过zhuhw. 进行范文里面的内容
- zhuhw{tag:function(){},setBorder:funtion{}}
- 全局变量污染解决
- 解决混乱
- getEle{tag:function(){}}
- setStyle{setBorder:function(){}}
- 解决混乱
- 动画模块
- 事件模块
- 命名空间
- 使用方式:
- 命名空间.模块.方法
- 面向对象编程的优势
- 避免了全局变量污染
- 将代码进行了模块划分,结果清晰,便于维护 11/26/2016 9:25:32 AM
创建对象的方式
- 字面量
- {}
- 存在的问题
- 代码复用性太差,每次创建的对象都需要手动的所有成员
- 存在的问题
- {}
- 使用内置构造函数
- var p = new Object();
- 自己添加属性 p.name =’’;
- 使用内置构造函数创建对象,创建出来的都是空对象,
- 需要手动的去添加属性和方法
- 复用性不好
创建对象的方式(自定义构造函数)
构造函数
- 构造函数是一个函数,一般用来初始化对象
- 特点:
- 首字母大写
- 一般和new关键字一起使用
- 不需要手动书写return语句,会默认的返回创建粗来的对象
- 创建一个人
- 构造函数的执行过程
- 首先使用new关键字来创建对象
- 调用构造函数,将构造函数的ths赋值为new 创建出来的对象
- 在构造函数内部使用this为新创建女出来的对象新增成员(初始化过程)
- 默认的返回刚才创建的对象
- 返回值的注意事项
- 如果手动写return语句
- 如果返回的是值类型的数据,则对原来的返回值,没有影响
- null 这边是简单类型,没影响
- 如果返回的是引用类型的数据,则替换原来的返回值
- 如果返回的是值类型的数据,则对原来的返回值,没有影响
- 如果手动写return语句
- 传参数就可以改变值
扩展:构造函数能不能像正常函数使用
- 普通的函数,直接是window调用
- 构造函数
- 可以调用,但是构造函数的this,会指向window对象
传统构造函数存在的问题
- 写一个函数用来创建dog对象
- Dog
- 属性: type gender
- 方法: bark
- 新建一个对象
- 函数执行完成后被回收
- 引用类型比较的时候是比较的地址
- 如果在构造函数内部创建函数,并且给对象新增方法,哪儿通过构造函数创建出来对象,每个对象都会独占一份,所以造成资源浪费
解决函数问题
- 解决方案
- 在构造函数创建指定函数
- 在构造函数内部为对象新增方法的时候,不徐娅在创建函数,而是直接用在外部创建好的函数的地址 2 存在的问题
- 胡造成全局变量污染
- 代码结构右混乱了
原型
1. 原型 1. 在构造函数创建出来的时候,系统会默认的帮这个构造函数创建并且关联一个空对象
- 原型的访问方式
- 构造函数.prototype
- 打印一个对象
- 原型的作用
- 所有成员都可以被
- 补充的一些小概念
- 实例
- 通过供函数创建出来的对象,可以成为该构造函数的一个实例
- 实例化
- 通过构造函数来
- 实例
-
使用原型解决构造函数存在的问题 1. 将方法的定义放在原型中,所有的对象都可以取共享该方法了,也不会造成资源的浪费
- 作用
- 可以
- 回答
- 构造函数的属性
- 注意区分构造函数的属性
- 和对象的属性
原型的使用
- 利用对象的动态特性为原型添加成员
- 直接替换了原型对象
- 直接个一个新的对象进行替换
- 系统自己的还有吗?? 多出来的???
原型的使用注意事项
- 使用对象.属性名去获取对象属性的时候,会现在自己种进行查找,如果没有,就去原型
- 如果设置对象属性的时候,只会在在吱声查找,如果有就修改,如果没有就添加
- 是复制一份吗???属性
-
一半请下,不会讲属性防放在原型当中,只会将方法放在原型中
- 直接Person.prototype{}
- 解释怎么存储的
- 画图
- 在替换原型的时候,替换之前替换的对象,和替换只会的对象那个的原型不一致
- 对象关联的原型就是创建对象那一刻,构造函数的prototype属性
- 在创建一个对象,可以访问最后一次创建的吗???
- 访问—先自己 再原型
- 设置 – 自己没有,设置;有,替换
- 公用的放在原型,独有的自己
- 替换之前对象,替换之后的对象,原型吧托尼盖
- 对象关联的
- 最后一个得到的
- 中间 写代码 画图
proto
- proto
- 是一个非标砖的属性,最早由火狐提出来,一半情况下,不推荐使用该属性来操作原型对象
- 因为不是标准的,有可能出现不兼容
- 稳定性问题
- 保证一致性
- 什么时候使用
- 只在调试的时候使用…
- 是一个非标砖的属性,最早由火狐提出来,一半情况下,不推荐使用该属性来操作原型对象
- 一半情况下
- ————开头的属性都是非标准的属性
- ——单下划线的属性,私有的属性(只是在自己用,不推荐在外面用)
- 构造函数名.prototype(推荐使用)
- 对象名.proto (一般调试)
11/26/2016 11:39:09 AM 11/26/2016 1:44:10 PM js事件万物诞生记
09———————-
- 疑问
- 变量设置 是直接在自己里面设置
- 创建了2个,创建了两个对象 后面又写了一次… 第二个 还是 最新的… 原因是在创建的时候进行有对象的
11/26/2016 2:40:53 PM
继承再看
- 混入时继承
- 原型继承:
- 使用原型实现的继承就是原型继承
- 方式
- 通过修改原型队形实现继承
- 利用混入的方式,为原型对象添加对象
- Person创建出来的而对想都是继承hu的
- 利用混入的方式,为原型对象添加对象
- 通过替换原型对象实现继承
- Person.prototype = hu;
- 直接human给person的原型不行吗????
- Person.prototype = hu;
- 通过修改原型队形实现继承
- 扩展
- 赋值额继承距离
- 继承时基于对象的 先创建一个对象在 Human.proto = ani; 注意
- 灰色的 构造函数的名称
- Animal解释
- 原型的const属性
- 原型对象那个中有一个属性. constructor
- 这个属性就执行那个跟该原型对象相关的构造函数
- 当创建出来构造函数—原型 (同时创建出来的)
- 先
- 在替换原型对象智慧和,constructor属性会丢失
- 自己指回来,没变之前的线还在吗?????——————–???construction有多根线
- 当创建出来构造函数—原型 (同时创建出来的)
- 原型
- 给其添加一个属性,
- 取值的时候,先函数再原型 ——是的
- 赋值的时候,函数自己有就是替换
- 原型有呢? 会是复制出来一份替换吗?(给自己—-不出现复制出来一份,因为本来就是自己的,有就改,没有就添加进去)
- —–不会去原型里面找,这个是规定
- 原型有呢? 会是复制出来一份替换吗?(给自己—-不出现复制出来一份,因为本来就是自己的,有就改,没有就添加进去)
- 给其添加一个属性,
- 原型的那根线
- prototy— 只有一个指向 ——-是的
- constructor—各是各的???——是的
——————–完成
11/26/2016 3:36:18 PM
原型链
- 每个对象都有原型对象,原型对象也是一个对象,所以原型对象也有原型对象,这样就形成了一个链式的结构,这个链式结构就称为原型链
- 分析
- p–>Person.prottype–>Obj.prottype—>null
- function Person(){} var p = new Person();
- 原型链练习
- arr–>Array–>Obj—>null
- [] 特殊点
- date —>Data.p—>Obj. —>null
- reg —>RegExp.p—>Obj. —>null
- 会说
- 最后一环都是obj
- arr–>Array–>Obj—>null
属性搜索原则
- 在使用对象进行属性获取的时候,会准准一下的属性搜索原则
- 现在对象本身中查找,如果找到了就直接使用
- 如果没有找到,就去对象的原型对象中参照,如果找到
- 如果没有找到,就去原行政进行找….
- 如果没有找到,就沿着
- 注意
- 设置属性的时候,不会使用属性搜索原则
- 只看自己
- 设置属性的时候,不会使用属性搜索原则
- 例子
继承的作用
- 当前的用的最多的—面试
- 继承应用举例
- 注意
- 不能直接修改系统的内置对象
- 因为内置对象被所有人共享,如果所有人都去修改内置对象
- 那么会造成不确定性
- 注意
- 如何安全的扩展内置对象
- 写一个构造函数
- 将Arr一个对象给他
- 完了之后就是一个新的,自己改不会影响内置对象
- array实例的 本是没有的,就自己再去找自己的原型—画图出来的
- 注意
- String的不可以通过自己创建…,只能通过修改包装类型
- trim
- 给string扩展方法
instanceof
- 作用
- 判断一个对象是不是某个构造函数的实例(不够精确)
- 解决办法
- 判断一个构造函数的原型是不是在该对象的原型链上
- 例子
- p–>Person.pro—>Obj.pro—>null
Obj.pro的成员介绍
- 监视
- console.log显示不可靠
- 在watch看对象的属性和方法
- 属性
- constructor属性
- 指向和原型相关的构造函数
- hasOwnProperty方法
- 判断一个对象自身是否有的属性
- 返回值有或者没有,是一个布尔值(原型中的属性不是自身的属性)
- in关键字操不管你是原型里的还是自身的,只要有就是true
- isPrototypeOf 方法
- 对象名.isPrototypeOf(对象1)
- 功能
- 判断对象是不是对象1的原型对象
- propertyIsEnumerable方法
- 对行吗.propertyIsEnumerable(属性名)
- 功能:
- 判断对象本身中是否拥有某个属性(原型中的不算) 并且
- 判断对象的指定的属性讷讷个否被遍历(for-in)到
- toLocalString toString 1. 功能一样的地方 1. 都是讲对象转换成字符串 2. toLocalString 1. 会将对象以本地格式打印出来(计算机本身) 3. toString 1. 会直接将对象以字符串的格式打印,跟本地格式无关
- valueOf
- 获取对象的值
- 功能
- 当对象类型和值类型参与运算的时候
- 1
- 一个小例子
- __proto__对象
- 指向对象的原型对象 11/26/2016 5:22:55 PM
- constructor属性
js高级第二天
面向对象举例
创建对象的方式
原型
继承
原型链
Object.prototype的成员
11/26/2016 6:46:55 PM
复习
面向对象编程的举例
- 直接进行写函数的方式
- 代码复用性太低
- 函数封装
- 进行封装两个行数
- 使用函数封装存在的问题:
- 全局污染,使用命名空间
- function在全局的会出现 全局污染 和 混乱不方便管理
- 面向对象编程的优势
- 优势
- 命名空间 :避免了全局变量污染
- 函数分模块模块:将代码进行了模块的划分,结构清晰,便于维护
-
代码
//设置命名空间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);
- 优势
创建对象的方式
- 字面量{}
- 代码复用性太差,每次进行创建的对象都需要手动的添加所有的成员对象
-
代码
var p1 = { name:'wa', sayP1:function(){ console.log('---p1---'); } };
- 内置构造函数 new的方式
- 创建出来的对象都是空对象,属性和方法需要自己添加
-
代码
var p3 = new Object(); p3.name = 'qg'; p3.sayHi = function(){ console.log('----p3-----'); }; p3.sayHi();//----p3-----
- 自定义构造函数
构造函数
- 概念
- 构造函数是一个函数,一般用来初始化对象
- 构造函数的特点
- 首字母大写
- 一般和new关键字一起使用
- 不需要手动书写return语句,会默认的返回创建出来的对象
- Person构造
-
代码
/*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();
-
- 构造函数的执行过程
- 首先使用new关键字来创建对象
- 调用构造函数,将构造函数内的this赋值为new创建出来的对象
- 在构造函数内部使用this为新创建出来的对象新增成员(初始化过程)
- 默认的返回刚才创建出来的对象
- 返回值的注意事项
- 如果手动写return语句,
- 如果返回的是值类型的数据,则对原来的返回值,没有任何影响(包括null)
- 如果返回的是引用类型的数据,则替换原来的返回值
-
代码
function test(){ this.name = 'kag'; console.log(this); } test();//返回的是一个window对象
- 如果手动写return语句,
传统的构造函数存在的问题
- 解释
- 如果在构造函数内部创建函数,并且给对象新增方法,
- 那么通过构造函数创建出来的对象,每个对象都会独占一个方法
- 所以会造成资源浪费
-
代码
/*写一个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
- 补充
-
代码
注意: 对象比较的是地址,两个function和下面的{}对象存在两个不同的地址上 console.log(function(){}==function(){});//false console.log({}=={});//false
-
解决普通构造函数问题方法一
- 在构造函数外部创建指定函数
- 在构造函数内部为对象新增方法的时候,不需要再创建函数,而是直接用在外部创建好的函数的地址
- 代码
- 写一个构造函数,用来创建狗对象
- 将函数放置在构造函数外部
-
代码
/* * 存在的问题: * 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 ## 原型的基本概念 ##
- 在构造函数创建出来的时候,系统会默认的帮这个构造函数创建并且关联一个空的对象,这个对象就是原型
- 原型的访问方式
- 构造函数名.prototype
- 原型的作用
- 构造函数的原型中的所有成员,都可以被该构造函数创建出来的对象访问(共享)
- 补充的一些小概念
- 实例:通过构造函数创建出来的对象,可以称为该构造函数的一个实例
- 实例化:通过构造函数来创建对象的过程,就是实例化
- 使用原型解决构造函数存在的问题
- 将方法的定义放在原型中,所有的对象就都可以去共享该方法了,也就不会出现资源浪费的情况
-
代码
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
原型的使用方式
- 利用对象的动态特性为原型添加成员
- 替换原型对象
-
代码
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(…)
原型的使用注意事项
- 对象.属性名 获取和设置属性
- 使用对象.属性名去获取对象属性的时候
- 会先在自身中进行查找,如果没有,就去原型中查找
- 使用对象.属性名去设置对象属性的时候,
- 只会在自身进行查找,如果有,就修改,如果没有,就添加
- 不会去原型中去找,自己有就修改,没有就添加
- 使用对象.属性名去获取对象属性的时候
-
代码案例
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);//张三丰
- 替换原型
- 在替换原型的时候,替换之前创建的对象,和替换之后创建的对象的原型不一致!!!
- 对象关联的原型,就是创建对象那一刻,构造函数的prototype属性
-
代码案例
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__
- proto
- 是一个非标准的属性,最早由firefox提出来
- 一般情况下 ,不推荐使用该属性来直接操作原型对象
- 由于兼容性问题,不推荐使用
- 由于稳定性问题,不推荐使用
- 只在调试的时候使用。。
- 访问原型的方式
- 构造函数名.prototype
- 对象名.proto
- 一般情况下
- __开头的属性都是非标准的属性
- _开头的属性,私有的属性
-
代码
function Person(){ }; console.log(Person.prototype);//Object {} var p = new Person(); console.log(p.__proto__);//Object {} p的原型是一个空的对象 console.log(Person.prototype==p.__proto__);//true
继承再探
- js中继承的方式
- 混入式继承
- 原型继承 使用原型实现的继承就是原型继承
- 通过修改原型对象实现继承
- 利用混入的方式,为原型对象添加成员
- 通过替换原型对象实现继承
- 通过修改原型对象实现继承
-
混入式继承代码
混入式继承 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中的值
-
原型继承 使用原型实现的继承就是原型继承
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
-
通过替换原型对象实现继承
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}
复杂的继承举例(不要求掌握)
-
代码案例
<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
- 原型对象中有一个属性 .constructor
- 这个属性就指向跟该原型对象相关的构造函数
- 在替换原型对象之后,constructor属性会丢失
-
代码案例
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>
原型链
- 原型链
- 每个对象都有原型对象,原型对象也是一个对象,所以呢原型对象也有原型对象
- 这样就形成了一个链式的结构,这个链式结构就称为 原型链
-
代码
function Person(){}; var p = new Person(); //p-->Person.prototype-->Object.prototype-->null console.log(Person.prototype);//Object {}
原型链练习
- js中的内置对象的原型
- 在当前环境下浏览器进行看的数据
-
代码
/* * 在当前环境下浏览器进行看的数据 * 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();
属性搜索原则
- 在使用对象进行属性获取的时候,会遵循以下的属性搜索原则
- 现在对象本身中进行查找,如果找到了就直接使用
- 如果没有找到,就去对象的原型对象中查找,如果找到了就直接使用
- 如果没有找到,就去原型对象的原型对象中进行查找,如果找到了就直接使用
- 如果没有找到,就沿着原型链继续往上查找,只到找到null为止
- 注意:
- 设置属性的时候,不会使用属性搜索原则
-
代码案例
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);//布加迪
继承应用继续举例
- 不能直接修改系统的内置对象
- 因为内置对象被所有人共享,如果所有人都去修改内置对象,那么会造成好多的不确定因素
-
代码案例
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
- 如何安全的扩展内置对象
- 新建一个对象
- 创建一个数组的对象的实例,
- 将这个实例所拥有的东西给新建对象的prototype
- 这个新对象就拥有了一系列属性和方法
-
代码案例
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
- 判断一个对象是不是某个构造函数的实例 (不够精确)
- 准确的说法是:
- 判断一个构造函数的原型是不是在该对象的原型链上
-
代码
//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