js函数prototype属性学习(一)

W3school上针对prototype属性是这么给出定义和用法的:使您有能力向对象添加属性和方法。再看w3school上给的那个实例,如下图:

仔细一看,原来最基本的作用就是对某些对象的属性、方法来扩展,我对这个实例又多写了几句代码进行测试,如下:

var steve= new empolyee("Steve Jobs","enterpriser",1977);

这里我专门查看了steve这个实体所拥有的属性,发现多了一个salary属性,这个属性是新建实体时未曾定义的,可见由于prototype的作用,employee这个对象有了新的属性salary,那么,prototype到底是何方神圣,它在js对象里到底有着怎样不可或缺的作用呢?

javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用。在javascript中并没有类的概念,但JavaScript中的确可以实现重载,多态,继承。这些实现其实方法都可以用JavaScript中的引用和变量作用域结合prototype来解释。原型法的主要思想是,现在有1个类A,我想要创建一个类B,这个类是以A为原型的,并且能进行扩展。我们称B的原型为A。

给人的感觉,A类就特别像java里的被继承的那个基础类,而B类继承后的实体子类,对B类的扩展就像多态,或者已有方法的重写,很面向对象有木有,这就是javascript带给我们最好的礼物,虽没有直接表明自己支持面向对象,但背地里却默默的支持着。再来看javascript的方法都有哪些种类。

1、类方法

var Person = {

};

Person.say = function(){

  alert("I can say language");

};

2、对象方法

function Person(name){

  this.name = name;

  this.interduceSelf= function(){

    alert("my name is " + this.name);

  };

};

3、原型方法

Person.prototype.interduceSelfChinses = function(){

  alert("我的名字是 " + this.name);

};

Person.say();

var person1 = new Person("xiaoming");

person1.interduceSelf();  //结果是my name is xiaoming

person1.interduceSelfChinses(); //结果是 我的名字是 xiaoming

var person2 = new Person("xiaozhang");

person2.interduceSelf(); //结果是my name is xiaozhang

person2.interduceSelfChinese(); //结果是 我的名字是 xiaozhang

由此我们可以看到,只要新增了一个对象的prototype属性中的方法,这个方法就成为了这对象的共有方法,不管你后来新建的是什么实体,都具有了这个共有方法,并且存在于它的_proto_属性里,如图:

可以看到,并没有对所有的人赋予新方法interduceSelfChinese,都自动的就有这个公共方法了,这是因为当一个对象被创建时,构造函数会把它的属性prototype赋给新对象的内部属性_proto_,这个_proto_属性被这个对象用来查找它的prototype属性,包括里面的属性、方法,都被查找出来,该调用时即调用。这样就有一个好处了,你不需要每次在构造一个对象的时候创建并初始化这个函数,继承就这样实现了,只不过严格的说,js并没提供继承这个概念,可以说新建的实体都是原来对象的一个拷贝,并且这个拷贝很活泛,可以重新写里面的属性和方法,同时还可以新增你想要的属性或方法,来看下面这个例子:

function FatherClass(){

  this.class = "father";

  this.setAuthority = function(){

    this.authority = "controller";

  };

};

var child = new function(){};

child.prototype = new FatherClass();

child.prototype.class = "child";

child.prototype.setAuthority = function(){

  this.authority = "controlled"; 

};

child.say = function(){   //新增方法,直接针对新对象加上即可

  alert("you can‘t controll me");

};

alert(child.class);  //结果为child

alert(child.authority); //结果为controlled

child.say(); //结果为you can‘t controll me

从上面可以看出,函数式的编程还是博大精深的,这就是一门编程语言的艺术。同时,在外部不能通过prototype改变自定义类型的属性或方法。该例子可以看到:调用的属性和方法仍是最初定义的结果。即当原型方法和对象方法在调用相同的属性和函数时,会执行对象方法里面的属性和函数。再看下面的例子:

function FatherClass(){

  this.class = "father";

  this.setAuthority = function(){

    this.authority = "controller";

  };

};

FatherClass.prototype.class = "child";

FatherClass.prototype.setAuthority = function(){

  this.authority = "controlled"; 

};

alert(FatherClass.class); //结果仍然为father

alert(FatherClass.authority); //结果仍然为controller

也就是说,不能直接通过prototype属性来修改对象本身以及有的属性、方法,要么新建一个拷贝它的实体再来修改,要么就新增属性或方法。

再来理解这2个东西,

1、A.prototype = new B();

2、A.prototype = B.prototype;

先来看A.prototype = new B(),理解prototype不应把它和继承混淆。A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍。A能使用B的方法和属性。这里强调的是克隆而不是继承。可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例。

function baseClass(){

   this.showMsg = function(){

     alert("baseClass::showMsg");

   }

} ;

function extendClass(){};

extendClass.prototype = new baseClass();

var instance = new extendClass();

instance.showMsg();   //结果是baseClass:showMsg

这里我们以baseClass的一个实例来做原型,来克隆的extendClass也同时包含了showMsg这个方法。extendClass.prototype = new baseClass()就可以阅读为:extendClass是以baseClass的一个实例为原型克隆创建的。但是当extendClass中有个与showMsg同名同参的函数时,调用这个函数会出现什么情况?再看这个例子:

function baseClass(){

  this.showMsg = function(){

    alert("baseClass:showMsg base");

  }

};

function extendClass(){

  this.showMsg = function(){

    alert("extendClass:showMsg extend");

  }

};

extendClass.prototype = new baseClass();

var extendA = new extendClass();

extendA.showMsg();  // 结果为extendClass:showMsg extend

从这里可以看出,函数运行时会先去本体的函数中去找,如果找到则运行,找不到则去prototype中寻找函数。或者可以理解为prototype不会克隆同名函数。如果要想直接调用原来类里的那个同名方法怎么办?可以用call()方法来实现,再写如下代码:

extendClass.prototype = new baseClass();

var instance = new extendClass();

var baseinstance = new baseClass();

baseinstance.showMsg.call(instance); //结果是baseClass::showMsg base

这里的baseinstance.showMsg.call(instance);阅读为“将instance当做baseinstance来调用,调用它的对象方法showMsg”

再看A.prototype = B.prototype,A的prototype为B的prototype,可以理解A将B的prototype中方法和属性全部克隆了一遍。A能使用B的prototype方法和属性。这里强调的也是克隆而不是继承。请看下面一个例子:

function Blog(url,name){

  this.url = url;

  this.name = name;

};

Blog.prototype.jumpurl = ‘‘;

Blog.prototype.jump = function(){

  window.location = this.jumpurl;

};

var blog1 = new Blog(‘dearxiangxiao‘, ‘https://home.cnblogs.com/u/xiangxiao/‘);

var blog2 = new Blog(‘希希里之海‘, ‘http://www.cnblogs.com/weixuqin/‘);

var webBlog = function(){};

webBlog.prototype = Blog.prototype;

var myWebBlog = new webBlog();

从上面的执行结果可以看出,myWebBlog的两个属性jump和jumpUrl分别引用了Blog.prototype.jumpurl和Blog.prototype.jump,由此可见,对象的prototype也可作为另一个对象的prototype的引用。

结束语:感觉js里面对类和实体对象对于方法的声明并无多大讲究,类方法也可直接拿来用,要知道,在java里可必须是抽象方法才允许这么调用的。

时间: 2024-12-23 13:24:26

js函数prototype属性学习(一)的相关文章

js函数prototype属性学习(二)

继续探讨js对象的prototype属性,前面已经看到在创建完一个对戏之后,随时都会有一个_proto_属性伴随所有,那么,这个_proto_又是用来干嘛的,面试时问的高大上的原型链又是怎么回事? 拿出前面已经有的例子,如下: function Person(name){ this.name = name; this.interduceSelf= function(){ alert("my name is " + this.name); }; }; Person.prototype.i

简单理解js的prototype属性

在进入正文之前,我得先说说我认识js的prototype这个东西的曲折过程. 百度js的prototype的文章,先看看,W3School关于prototype的介绍: 你觉得这概念适合定义js的prototype这个东西吗?你是否也认为prototype是一个object对象的属性呢?是的话,请认真认真看我这篇文章,因为这篇文章会毁灭你的人生三观,呵呵,就是有这么严重,因为本人就是被这个定义给害惨的. 不得不说,看了网上的一些介绍prototype的文章,基本上都说prototype是对象的一

js中Prototype属性解释及常用方法

1.prototype的定义 javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用. 每一个构造函数都有一个属性叫做原型.这个属性非常有用:为一个特定类声明通用的变量或者函数. 你不需要显式地声明一个prototype属性,因为在每一个构造函数中都有它的存在.你可以看看下面的例子: function Test(){} alert(Test.prototype); // 输出 "Object" 1.

JS函数的属性

1.arguments.callee //经典的阶乘(递归)函数 function factorial(num) { if (num <= 1) { return 1; } else { return num * factorial(num - 1); } } //消除函数名的耦合现象 function factorial(num) { if (num <= 1) { return 1; } else { return num * arguments.callee(num - 1);//函数内

js的Prototype属性 解释及常用方法

JavaScript能够实现的面向对象的特征有: ·公有属性(public field) ·公有方法(public Method) ·私有属性(private field) ·私有方法(private field) ·方法重载(method overload) ·构造函数(constructor) ·事件(event) ·单一继承(single inherit) ·子类重写父类的属性或方法(override) ·静态属性或方法(static member) 例子一(JavaScript中允许添加

Js的prototype属性

prototype作用在JS中的对象上,可以为对象添加属性和方法. 语法:object.prototype.name=value 细节:当通过一个类创建对象以后,当通过对象访问属性的时候,JS查找属性的顺序是: 1.对象本身的属性,比如 obj={} obj.age=18 2.对象的类的prototype中查找,比如 obj={} obj.prototype.age=18 3.对象的根对象(object对象)中查找 4.当一个对象的类定义之后,可以通过prototype为对象的类添加新的属性和方

js原型prototype属性用法实例

//原型方法创建对象的属性和方法,达到共享的目的 function Box(){};//里面什么都没有,如果有就是实例属性和方法 Box.prototype.name='tianwei'; Box.prototype.age='100'; Box.prototype.run=function(){ return this.name+this.age; }; var box1=new Box(); document.write(box1.name); 实例属性不会共享,原型属性共享,优先访问实例属

JS中prototype属性-JS原型模式

1 /* 2 *对象方法 3 *类方法 4 * 原型方法 5 */ 6 function People(name) { 7 this.name = name; 8 this.say = function () { //对象方法 9 alert("my name is "+this.name); 10 } 11 } 12 13 People.run = function () { //类方法(静态方法,只能由类名调用) 14 alert("i can run"); 1

JS学习之prototype属性

javascript中的每个对象都有prototype属性,Javascript中对象的prototype属性的解释是:返回对象类型原型的引用.以A.prototype = new B();为例, 理解prototype不应把它和继承混淆,A的prototype为B的一个实例,可以理解A将B中的方法和属性全部克隆了一遍,A可以使用B的方法和属性,这里强调的是克隆而不是继承,可以出现这种情况:A的prototype是B的实例,同时B的prototype也是A的实例. 1 function base