首页 > 代码库 > prototype属性
prototype属性
Apply调用模式
javaScript是一门函数式的面向对象编程语言,所以函数可以拥有方法。函数的apply方法,如同该对象拥有此方法,此时this指向该对象。
构造器调用模式 ##
javaScript是一门基于原型继承的语言,这以为这对象可以直接从其他对象继承属性,该语言是无类别的。
如果一个函数前面带上new来调用,name将创建一个隐藏连接到该函数的prototype成员的新对象,同时this将会绑定到构造函数的实例上。
jQuery为开发插件提供了两个方法,分别是: jQuery.fn.extend(object);//为扩展jQuery本身,为类添加方法; jQuery.extend(object);//给jQuery对象添加方法
javaScript中对象的prototype可以返回对象类型的原型引用。
jQuery.fn = jQuery.prototype = { init: function(selectot, context){ } }
init = jQuery.fn.init = function(selector,context){};
init.prototype = jQuery.fn;
rootjQuery = jQuery(document);
prototype属性能够给对象添加属性和方法:object.prototype.name = value
eg:
function employee(name, job, born){
this.name = name;
this.job = job;
this.born = born;
}
var bill = new employee("bill", "engineer", "1994-10-07");
employee.prototype.salary = null;
bill.salary = 2000;
documnet.write(bill.salary);
总结
- 可以在类型上使用prototype来为类型添加行为,这些行为只能在类型的实例上体现
- 实例上不能使用prototype,否则会发生编译错误
- 可以为类型添加静态的属性和方法,直接在类型上调用即可:Object.method=function(){alert("this is static method"};
在面向对象的语言中,如java存在类(class)的概念,类就是对象的魔板,对象是类的实例。但是在javaScript的语言体系中,是不存在类(class)的概念的,javaScript中不是基于‘类’的,而是通过构造函数(cinstructor)和原型链(prototype chains)实现的。但是在ES6中提供了更接传统语言的写法,引入了Class(类)的概念,作为对象的魔板,ES5都可以做到,新的Class写法是让原型对象的写法更加清晰、更加像面向对象的语法而已。
构造函数的缺点:同一个构造函数的对象实例之间不能共享属性或方法。js中提供了prototype属性来解决这个问题。
js中每一个数据类型都是对象(除了null,underfined),而每一个对象都继承另外一个对象,后者成为“原型”(prototype)对象,只有null除外,他没有自己的原型对象。原型对象的所有属性和方法,都可以被对象的实例所共享
对于构造函数来说,prototype是作为构造函数的属性;对于对象实例来说,prottype是对象实例的原型对象。所以,prototype既是属性也是对象。
原型对象的属性不是对象实例的属性。对象实例的属性是继承自构造函数定义的属性,因为构造函数内部有一个this关键字来指向要生成的对象实例。对象实例的属性,其实就是构造函数内部定义的属性。只要修改原型对象上的属性和方法,变动就会立刻体现在所有对象实例上。
eg: function Person(name, height){ this.name = name; this.height = height; } Person.prototype.hobby = function(){ return ‘shopping‘; } var boy = new Person(‘k‘,180); var girl =new Person(‘r‘,163); console.log(boy.name); // k console.log(girl.name); // r console.log(boy.hobby === girl.hobby); //true Person.prototype.hobby = function(){ return ‘eating‘; } console.log(boy.hobby === girl.hobby); //true console.log(boy.hobby); //eating console.log(girl.hobby); //eating
当我们修改boy对象的hobby方法时就不会再继续继承原型对象上的hobby方法了,不过girl仍然会继承原型对象的方法。
boy.hobby = function(){ return ‘play basketball‘; } console.log(boy.hobby); //play basketball console.log(girl.hobby); //eating
总结:a:原型对象的作用就是定义所有对象实例所共享的属性和方法。b:prototype对于构造函数来说它是属性,对于对象的实例来说它是一个原型对象
原型链
对象的属性和方法,有可能定义在自身,也有可能定义在它的原型对象。
由于原型对象本身对于对象实例来说也是对象,它也有自己的原型,所以形成了一条原型链(prototype chain)。比如,a对象是b对象的原型,b对象是c对象的原型,一次类推。所有一切的原型顶端,都是Object.prototype,即Object构造函数的prototype属性指向的那个对象。
当然Object.prototype也有自己的原型对象,那就是没有任何属性和方法的null对象,而null对象没有自己的原型。 1.console.log(Object.getPrototypeOf(Object.prototype)); // null 2.console.log(Person.prototype.isPrototypeOf(boy)); //true
原型链(Prototype chain)的特点
a.读取对象的某个属性时,javaScript引擎先寻找对象本身的属性,如果找不到,就找到他的原型去找,如果还找不到,就到原型的原型去找。如果找到最顶层的Object.prototype还是找不到,则返回undefined。 b.如果对象自身和它的原型,都定义了一个同名属性,那么优先读取对象自身的属性,这叫做“覆盖”。 c.一级级向上在原型链寻找某个属性,对性能是有影响的。所寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找不到某个不存在的属性,将会遍历整个原型链。
constructor属性
prototype对象有一个constructor属性,默认指向prototype对象所在的构造函数。
function A(){}; console.log(A.prototype.constructor === A); //true console.log(A.prototype.constructor ===A()); //false console.log(A.prototype.constructor ===A(){});//语法编译出错
要注意的是,prototype是构造函数的属性,而constructor则是构造函数的prototype属性所指向的那个对象,也就是原型对象的属性。注意不要混淆。
由于constructor属性是定义在原型(prototype)对象上面,意味着可以被所有实例对象继承。
constructor属性的作用
a.分辨原型对象属于那个构造函数
function A(){}; var a = new A(); console.log(a.constructor === A); //true console.log(a.constructor === Array); //false
b.从实例新建另外一个实例
function A(){}; var a = new A(); var b = new a.constructor(); console.log(b instanceof A);
c.调用自身的构造函数成为可能
A.prototype.hello = function(){ return new this.constuctor(); }
d.提供了一种从构造函数到另外一种构造函数的模式
function Father(){}; function Son(){ Son.height.constructor.call(); };
这里存在问题 call()
e.由于constructor属性是一种原型对象和构造函数的关系,所以在修改修改原型的时候,一定要哦注意constructor的指向问题。 解决方法有两种:1.将consructor属性指向原来的构造函数。2.只在原型对象上添加属性和方法。
instanceof运算符
instanceof运算符返回一个布尔值,表示指定对象是否为某个构造函数的实例。
function A(){}; var a = new A(); console.log(a instanceof A); //true
因为instanceof对整个原型链上的对象都有效,所以同一个实例对象,可能会对多个构造函数都返回true。只能用于复杂数据类型(数组、对象等),不能用于简单数据类型(布尔值、数字、字符串等)
jQuery对象和DOM对象的相互转换
jQuery提供了2种方法将jQuery对象转换成DOM对象,即[index]和get(index)。就是通过数组下标的方式,jQuery对象是一个数组对象。
var $a = $("#a");//jQuery对象 var a = $a[0]; //dom对象 // 或者: var a = $a.get(0);
prototype属性