手机版

JavaScript原型使用介绍

时间:2021-11-16 来源:互联网 编辑:宝哥软件园 浏览:

使用过JavaScript的同学一定对原型了如指掌,但初学者对它是什么却不能达成一致。他们只知道所有的函数都有一个原型属性,可以为其添加函数进行实例访问。其他人不清楚。最近看了一些JavaScript高级编程,它们的奥秘终于揭开了。每个函数都有一个原型属性,它是对一个对象的引用,这个对象被称为原型对象。原型对象包含函数实例共享的方法和属性,也就是说,当函数用作构造函数调用(用new运算符调用)时,新创建的对象将从原型对象继承属性和方法。私有变量和函数在具体讲原型之前,先说几个相关的东西,可以更好的理解原型的设计意图。JavaScript的函数范围在之前写的一篇关于JavaScript命名空间的文章中提到过。如果函数中定义的变量和函数不提供外部接口,外部将无法访问,即成为私有变量和私有函数。复制的代码如下: function Obj(){ var a=0;//私有变量var fn=function(){//private function } }这样,变量a和函数fn就不能在函数Object Obj之外访问,它们变成私有的,只能在Obj内部使用。即使是函数obj的一个实例也仍然不能访问这些变量和函数。复制它们的代码如下: var o=new Obj();console . log(o . a);//未定义的console . log(o . fn);//未定义的静态变量和函数当一个函数被定义时,由“.”添加的属性和函数仍然可以通过对象本身进行访问,但是不能访问它的实例。这样的变量和函数分别称为静态变量和静态函数。使用过Java和C#的同学都能很好的理解静态的含义。复制的代码如下: function Obj(){ } Obj . a=0;//Static变量obj . fn=function(){//Static function } console . log(obj . a);//0 console . log(type of Obj . fn);//函数var o=new Obj();console . log(o . a);//未定义的console.log(类型为o . fn);//未定义的实例变量和函数在面向对象编程中,除了一些库函数之外,我们在定义对象的时候还是要同时定义一些属性和方法,实例化之后就可以访问,JavaScript也可以复制代码如下: function Obj(){ this . a=[];//实例变量this . fn=function(){//instance method } } console . log(type of Obj . a);//undefined console . log(type of Obj . fn);//undefined var o=new Obj();console . log(o . a的类型);//对象console.log(类型为o . fn);//函数本可以达到上述目的,但复制代码如下: function Obj(){ this . a=[];//实例变量this.fn=function(){ //实例方法} } var O1=new Obj();O1 . a . push(1);O1 . fn={ };console . log(O1 . a);//[1] console.log(类型为O1 . fn);//对象var O2=new Obj();console . log(O2 . a);//[]console . log(O2 . fn的类型);//函数上面的代码完全按照预期运行,但它也显示了一个问题。a和fn在o1中被修饰,但在o2中没有改变。由于数组和函数都是Objects和reference两种类型,这说明o1和o2中的属性和方法不是引用,虽然它们有相同的名称,但它们是obj对象定义的属性和方法的副本。这对于属性来说不是问题,但是对于方法来说是一个大问题,因为方法都在执行完全相同的功能,但是它们被复制成两个副本。如果一个函数对象有几千个实例方法,那么它的每个实例都必须保留几千个方法的副本,这显然是不科学的,这是一个很大的问题。原型应运而生。每当prototype创建一个新函数时,它都会根据一组特定的规则为该函数创建一个prototype属性。默认情况下,原型属性将默认获得一个构造函数属性,它是原型属性所在函数的指针。其中一些被绕过了。写代码,如上图!复制的代码如下:函数person () {} image

从上图可以看出,Person对象会自动得到prototype属性,prototype也是一个对象,它会自动得到一个constructor属性,指向Person对象。当一个构造函数被调用来创建一个实例时,一个内部指针(在许多浏览器中被命名为__proto__)将被包含在该实例中,以指向该构造函数的原型。这种连接存在于实例和构造函数原型之间,但不存在于实例和构造函数之间。复制代码如下:功能人(姓名){this。name=name} person . prototype . print name=function(){ alert(this . name);} var Person 1=new Person(' Byron ');var person2=新人(' Frank ');image

Person1中包含了name属性,Person 1是Person的一个实例,会自动生成一个__proto__属性,指向Person的原型,可以访问原型中定义的printName方法,大概是这样的image

编写一个段程序来测试和查看原型中的属性。方法是共享和复制代码。代码如下:功能人(姓名){本。name=name} person . prototype . share=[];person . prototype . print name=function(){ alert(this . name);} var Person 1=new Person(' Byron ');var person2=新人(' Frank ');person 1 . share . push(1);person 2 . share . push(2);console . log(person 2 . share);//[1,2]果然!实际上,当代码读取一个对象的属性时,它将执行一次搜索。目标是具有给定名称的属性。搜索首先从对象实例开始,如果在实例中找到属性,则返回。如果找不到,就找原型。如果仍然没有找到,它将继续递归原型的原型对象,直到找到为止。如果仍然没有找到,它将返回一个错误。同样,如果在实例中定义了与原型同名的属性或函数,原型的属性或函数将被覆盖。复制代码如下:功能人(姓名){this。name=name} person . prototype . share=[];var Person=new Person(' Byron ');person . share=0;console . log(person . share);//0而不是原型中的[]来构造简单对象。当然,原型并不是为了解决上述问题而专门定义的,但它解决了上述问题。了解这些知识可以构建一个复用率很高的科学对象。如果想要实例对象的属性或函数,可以在prototype中定义它们,如果想要每个实例单独拥有的属性或方法,可以在这个中定义它们,并且可以通过构造函数传递实例化参数。复制代码如下:功能人(姓名){this。name=name} person . prototype . share=[];person . prototype . print name=function(){ alert(this . name);}作者:色拉油。

版权声明:JavaScript原型使用介绍是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。