JavaScript面向对象编程之prototype对象
来源:互联网 发布:微信打不开淘宝链接 编辑:程序博客网 时间:2024/05/21 19:30
1.同一个构造函数的对象实例之间,无法共享属性。
function Cat(name){ this.name=name; this.eat=function(){console.log("eat");}}var cat1=new Cat('a');var cat2=new Cat('b');console.log(cat1.eat===cat2.eat);//false//每新建一个实例会新建一个eat方法。这既没有必要,又浪费系统资源,因为所有eat方法都是同样的行为,完全应该共享。
2.A对象继承B对象,B对象是A对象的原型对象,A对象是B对象的派生对象。
3.所有对象都有构造函数,所有函数都有prototype属性,所以所有对象都有自己的原型对象,只有null对象没有原型对象。
4.原型对象的所有属性和方法,都能被派生对象共享。
5.每个构造函数都有一个prototype属性,通过构造函数生成实例对象时,实例对象的原型对象是这个prototype属性。
function Cat(name){ this.name=name;}Cat.prototype.color='white';var cat1=new Cat('a');var cat2=new Cat('b');console.log(cat1.color);//whiteconsole.log(cat1.color==cat2.color);//true
实例对象没有color属性,就会去读原型对象的color属性,如果实例对象有color属性,就不会去读原型对象的color属性。
function Cat(name){ this.name=name; this.eat=function(){console.log("eat");} } Cat.prototype.color='white'; var cat1=new Cat('a'); var cat2=new Cat('b'); cat1.color='black'; console.log(cat1.color);//black console.log(cat1.color==cat2.color);//false
6.原型链
所有对象都可以追溯到Object.prototype,即Object构造函数的prototype属性,Object.prototype的原型是null对象,null对象没有原型对象。
7.原型链的作用是:读取对象的某个属性时,JavaScript引擎先寻找对象本身的属性,如果找不到,就去它的原型对象上找,如果还是找不到,就到原型的原型上找,直到Object.prototype还是找不到,就返回undefined
8.如果对象和原型有同名属性,优先读取对象上的属性,这叫覆盖。
9.如果某个函数的prototype属性指向一个数组,那么该函数可以当做数组的构造函数,因为它的实例对象都可以调用数组方法。
function My(){}My.prototype=new Array;var a=new My;a.push(1,2);console.log(a);//[1,2]console.log(a instanceof Array);//true//instanceof运算符用于判断一个对象是否是某个构造函数的实例
10.某个属性是原型链上哪个对象自身的属性
function getDefiningObject(obj,key){ if(obj&&!{}.hasOwnProperty.call(obj,key)){ obj=Object.getPrototypeOf(obj); } return obj;}
11.prototype对象有一个constructor属性,默认指向构造函数。能够分辨实例对象属于哪个构造函数。
function Func(){}var a=new Func();console.log(a.constructor);console.log(a.constructor===Func.prototype.constructor);console.log(a.hasOwnProperty('constructor'));//function Func(){}//true//false
有了constructor属性,就可以从实例新建另一个实例。
function Func(){}var a=new Func();var b=new a.constructor();console.log(a instanceof Func);
修改prototype对象的时候,导致constructor指向改变,导致instanceof失真。
//constructor指向改变function Super() {}function Sub() {}Sub.prototype= new Super();console.log(Sub.prototype.constructor);//Supervar sub=new Sub();console.log(sub.constructor);//Superconsole.log(sub instanceof Super);//trueconsole.log(sub instanceof Sub);//truefunction Super() {}function Sub() {}Sub.prototype= new Super();Sub.prototype.constructor=Sub;//校正console.log(Sub.prototype.constructor);//Subvar sub=new Sub();console.log(sub.constructor);//Subconsole.log(sub instanceof Super);//trueconsole.log(sub instanceof Sub);//true//instanceof失真function A() {}var a = new A();console.log(a instanceof A );//truefunction B() {}A.prototype = B.prototype;//修改了A.prototypeconsole.log(a instanceof A );//false,instanceof失真console.log(a.constructor);//function A(){}
修改原型对象时,一般要同时校正constructor属性的指向。
避免完全覆盖掉原来的prototype属性。
通过name属性,可以从实例得到构造函数的名称。
function func(){}var a=new func();console.log(a.constructor.name);
12.instanceof运算符
判断是否为该构造函数的实例。运算实质:检查右边构造函数的prototype对象是否在左边对象的原型链上。
instanceof运算符的另一个用处,是判断值的类型。instanceof运算符只能用于对象,不适用原始类型的值。
var a=[1,2,3];var obj={};console.log(a instanceof Array);//trueconsole.log(a instanceof Object);//trueconsole.log(obj instanceof Array);//falseconsole.log(obj instanceof Object);//trueconsole.log(null instanceof Object); // falseconsole.log(undefined instanceof Object); // false,undefined和null不是对象var string="hello";console.log(string instanceof String);//false,因为字符串不是对象
13.Object.getPrototypeOf():返回对象的原型
console.log(Object.getPrototypeOf({}));//Objectconsole.log(Object.getPrototypeOf({})===Object.prototype);//trueconsole.log(Object.prototype.isPrototypeOf({}));//true
14.Object.setPrototypeOf():为现有对象设置原型对象,返回一个新对象
var a={x:2};var b=Object.setPrototypeOf({y:1},a);console.log(b.x,b.y);//2 1
15.Object.create():从原型对象生成新的实例对象,可以代替new命令
var obj={x:1};var a=Object.create(obj);console.log(a.x);//1
老式浏览器不支持Object.create()
if(typeof Object.create !=='function'){ Object.create=function(o){ function F(){} F.prototype=o; return new F(); }}
下面三种生成新对象的方法是等价的:
var obj1=new Object();var obj2=Object.create({});var obj3=Object.create(Object.prototype);
创建一个不继承任何属性方法的对象:
var o=Object.create(null);//继承null对象,不继承Object.prototype
Object.create()可以传入第二个参数,为新创建的对象添加属性
var obj={x:1};var a=Object.create(obj,{ p1:{value:1,enumerable:true}, p2:{value:2,enumerable:true},});console.log(a.x,a.p1,a.p2);//1 1 2
15.Object.prototype.isPrototypeOf():判断是否在原型链上
var o1={};var o2=Object.create(o1);console.log(Object.prototype.isPrototypeOf(o1));//trueconsole.log(o1.isPrototypeOf(o2));//truevar str=new String('123');console.log(Object.prototype.isPrototypeOf(str));//trueconsole.log(Object.prototype.isPrototypeOf('123'));//false
16.Object.prototype.__proto__:可以改写原型对象
var o={};var a={};a.__proto__=o;console.log(o.isPrototypeOf(a));//true
根据语言标准,proto属性只有浏览器才需要部署,其他环境可以没有这个属性,而且前后的两根下划线,表示它本质是一个内部属性,不应该对使用者暴露。因此,应该尽量少用这个属性,而是用Object.getPrototypeof()(读取)和Object.setPrototypeOf()(设置),进行原型对象的读写操作。
17.获取原型对象的方法:推荐第三种
obj.__proto__
obj.constructor.prototype
Object.getPrototypeOf()
- JavaScript面向对象编程之prototype对象
- JavaScript面向对象编程之prototype原型与继承
- JavaScript [面向对象] prototype
- javascript学习十一:面向对象之prototype
- JavaScript 面向对象之 原型-prototype
- JavaScript 之面向对象编程
- javascript [面向对象] prototype 分析
- javaScript 面向对象-原形prototype
- javascript面向对象编程之创建对象
- JavaScript面向对象编程之创建对象
- js面向对象编程-prototype
- JavaScript面向对象编程(3)prototype简介
- JavaScript面向对象编程(7)只继承prototype
- javascript中prototype方式面向对象编程注意事项
- js面向对象之prototype
- 面向对象之prototype,__proto__
- JavaScript 面向对象编程
- JavaScript 面向对象编程
- 防止SQL注入的五种方法
- eclipse端口被占用(java.net.BindException: Address already in use: bind)解决方法
- 画“猫”神器
- 230. Kth Smallest Element in a BST
- 从《货殖列传》中学习炒股
- JavaScript面向对象编程之prototype对象
- 有关hibernate的几个面试问题
- Android利用高德地图关键字检索POI,显示用户MD5安全码未通过
- 用简单工厂来创建对象和用new创建对象相比好处有哪些
- Linux:进程间通信
- Jmeter教程 简单的压力测试
- UIWebView 背景透明
- matlab找到图像的最大连通区域
- UIWebebView播放视频