深入javascript面向对象,js的原型链、继承
来源:互联网 发布:graphic软件 编辑:程序博客网 时间:2024/06/05 16:48
进阶面向对象——————————————————————–
在JS源码中,系统对象也是基于原型的程序,尽量不要去添加和修改系统对象的方法
包装对象——————————————————————–
基本类型都有自己对应的包装对象比如String Number Boolean基本类型会找到对应的包装对象类型,然后包装对象把所有的属性方法给了基本类型,然后包装对象消失例如
var str = 'abc'; str.num = 10; //创建一个包装对象,给包装对象加num属性,然后立刻消失。 //除非设置String.prototype.num = 10; alert(str.num); //这时候又创建了一个包装对象,和上面创建的那个没有关联, //所以显示undefined
原型链————————————————————————-
实例对象与原型之间的连接,叫做原型链在ff中的DOM能查看到:__proto__( 隐式连接 )对于一个对象来说,调用其方法或使用其属性,它会先看自己有没有该方法/属性,如果没找到,再通过__proto__向上查找它的原型,直至最顶层的原型ObjectObject对象类型是原型链的最外层 Object.prototype
面向对象的一些常用属性和方法—————————————————
obj.hasOwnProperty('name') : 查看对象/属性是否是对象本身的。 该方法是 Object.prototype的方法constructor : 查看对象的构造函数 还可以用来判断对象的类型 如:
var str = ''; alert(str.constructor===String);//true
另外,当声明一个构造函数时,系统会自动给xxx.prototype.constructor 赋值,如: function Person(){ } 系统会自动加上 Person.prototype.constructor=Person; 而且这是面向对象系统自动生成的唯一一段代码 但是如果用JSON Person.prototype = { attr1 : 10, fn1 : function(){} } 来给Person加对象加属性/方法的话,会覆盖系统自动生成的代码。 导致对象实例化以后,实例化对象.constructor 会通过原型链 (因为本构造函数没有这个属性)找到Object.constructor,从而 得到的值是Object 因此用JSON给对象写原型属性/方法时,要先给对象写construct 属性,并指向本身 For in 的时候有些系统自带属性prototype属性是找不到的 (自己添加的找得到) 避免修改construtor属性instanceof : 对象与构造函数在原型链上是否有关系 用法: person1 instanceof Person 在原型链上有关系就返回true 也可以用来判断对象是否是指定的属性 var arr = []; arr instanceof Array //truetoString() : 把对象转为字符串 是Object上的方法 系统对象下面的这个方法都是自带的,而自己写的对象都是通过 原型链找到Object下面的方法 Array对象的toString:返回数组的字符串形式 Number对象的toString(n):返回数字n进制的字符串形式 利用toString做类型的判断(最好) var arr=[]; alert( Object.prototype.toString.call(arr) );//[Object Array]; Object.prototype.toString.call(arr)==='[Object Array]'; 为真则是数组总结判断对象类型的三种方法:
obj.constructor === Array; obj instanceof Array; //以上两个在跨iframe,判断window.frames[i].Array;时不行 Object.prototype.toString.call(obj) === '[object Array]';
继承—————————————————————————
概念 : 在原有对象的基础上,略作修改,得到一个新的对象 不影响对象原有功能。好处 : 子类不影响父类,子类可以继承父类的一些功能 (代码复用)写法 : 属性继承:调用父类的的构造函数.call():
function Person(name,sex){ this.name = name; this.sex = sex; } function Star(name,sex,job){ Person.call(this,name,sex); //如果不改变this指向,function下的Person中的this指向window this.job = job; }
原型方法/属性的继承: 【拷贝继承】 父类的原型拷贝一份赋给子类, 这样就不会因为JS的引用机制,子类修改的原型属性方法影响父类 Star.prototype = deepCopy(Person.prototype); 【类式继承】 JS中没有类的概念,可以把构造函数等价于java中的类 类式继承写法:
function Father(){ this.name = '大明'; }; Father.prototype.callname = function(){ alert(this.name); }; function Child(){}; Child.prototype = new Father();//核心 var c1 = new Child(); c1.callname();//大明
原理:c1本身没有callname方法,于是找Child上的callname方法 Child.prototype上面也没有callname方法,于是找到new Father() 这个匿名对象上,这个实例对象本身也没有该方法,要通过原型链找到 Father.prototype上的callname方法,然后再调用 问题: Child.prototype = new Father();一句话覆盖了Child所有的prototype ,就连Child.prototype.constructor也被覆盖了,所以 c1.constructor也找不到了,要通过原型链找到其父级的constructor, 所以c1.constructor的值是Father。 因此为避免这个问题要手动修正Child.prtotype.constructor=Child; 此外,把this.name改为数组[1,2,3]; 创建一个实例对象对其进行操作 var c1 = new Child(); c1.name.push(4); var c2 = new Child(); alert(c2.name);//1,2,3,4 由此发现两个不同的实例对象居然会相互之间产生影响 原因是无论是c1还是c2,他们在读取name属性时都是在本身找不到, 而要通过原型链到匿名实例对象new Father()上找。所以操作的 是同一个地址。进而产生影响。 要避免这个问题,就要做到属性和方法分开继承。 function F(){};//1 F.prototype = Father.prototype;//2 Child.prototype = new F();//3 Child.prototype.constructor = Child;//4 //以上是类式继承的4句话 1句中声明的F构造函数没有属性。2句中F只继承了Father的原型方法, 自己并没有属性。3句中把一个F的实例对象赋值给Child的原型。 这样,如果实例化Child->c1调用c1.name,只能向上找F的实例对象上 有没有name这个属性,而由2句可知,F的实例对象是没有name这个属性 的,所以系统只会返回undefined 而如果c1调用方法callname,系统会通过原型链一直找到Father.prototype 从而调用Father.prototype上的callname方法。所以属性和方法继承 被分开了。 而继承属性的方法还是在Child构造函数中调用Father.call(this); 【原型继承】
function Father(){ this.name = '父亲'; } var f1 = new Father(); var c1 = cloneObj(f1); c1.name = '小米' //alert(c1.name)//小米 //alert(f1.name)//父亲 var a = { name : 'a' }; var b = cloneObj(a); b.name = 'b'; alert(b.name); alert(a.name); function cloneObj(obj){ function F(){}; F.prototype = obj; return new F(); }
【三种继承方式总结】 拷贝继承:通用型的 有new或无new的时候都可以使用 类式继承:适合new 构造函数 原型继承:适合无new的形式
0 0
- 深入javascript面向对象,js的原型链、继承
- [JavaScript面向对象编程指南]-深入理解JavaScript默认的继承方式——原型链
- JS面向对象的继承三种方法:原型继承,原型冒充继承,复制继承
- js面向对象之继承-原型继承
- 8-深入面向对象+原型链+继承(总结+note)
- js面向对象编程,一个完整原型的继承例子
- JS的面向对象-工厂方式-原型-继承
- JavaScript 面向对象与原型、继承
- JavaScript 面向对象思想以及原型、继承
- JavaScript 面向对象思想以及原型、继承
- JavaScript 面向对象思想以及原型、继承
- javascript面向对象(原型、继承)
- javaScript对象 原型深入理解 继承
- js面向对象原型和继承
- 什么是面向对象,原型,原型链继承
- JavaScript 面向对象(七)原型链深入
- JS面向对象-原型链的认知
- JavaScript面向对象-基于原型链和函数伪装组合的方式实现继承
- OC中类与对象的使用介绍
- HDU 2222 Keywords Search (AC自动机模板)
- js导入导出excel(实例代码)
- linux下底层函数实现MAC、IP地址以及网关地址
- Java灵活文档导出-Freemarker
- 深入javascript面向对象,js的原型链、继承
- Leetcode#41||First Missing Positive
- linux网络编程
- 最短路算法之Folyd算法
- OC中方法与函数的区别以及类的合理设计
- android开发之bitmap使用
- 继承WechatSupport类spring不能加注入
- js用第三方插件打印lodop
- TCP/IP/ICMP等报头结构体