首页 > 代码库 > 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属性