精华内容
下载资源
问答
  • 主要介绍了JavaScript中原型和原型链详解,本文讲解了私有变量函数、静态变量函数、实例变量函数、原型和原型链的基本概念,需要的朋友可以参考下
  • JS中原型和原型链

    2021-03-18 11:37:02
    今天学习JS的时候又遇到了原型和原型链的问题,原来记得看过了但是依然一头懵(其实就是忘了),今天又复习了一遍,在这里做个总结,方便以后再次复习,如果有什么错误,还希望大家多多留言指正! 一、概念 1....


    写在前面

    今天学习JS的时候又遇到了原型和原型链的问题,原来记得看过了但是依然一头懵(其实就是忘了),今天又复习了一遍,在这里做个总结,方便以后再次复习,如果有什么错误,还希望大家多多留言指正!


    一、概念

    1.分类

    原型分为显式原型(prototype)和隐式原型(proto)之分,构造函数会有显式原型,默认指向一个空object对象(当然Object的显式原型除外,下面会讲到),实例对象会有隐式原型(这里就不做解释什么是实例对象什么是构造函数了,不知道的小伙伴可以先学习一下再来阅读),隐式原型构造它的构造函数的显式原型。

    2.作用

    程序员可以通过操纵显式原型来实现属性的继承(这句话非常重要,下面详细解释)

    3.图解

    在这里插入图片描述


    二、原型

    首先我们先来看一段代码

    
    function Fn(){
    	this.test1=function (){
    		console.log('test1')
    	}
    }
    

    首先这段代码定义了一个简单地函数Fn,内部添加了一个名为test1的变量,并给它赋了一个函数,首先我们应该明白,这是一个构造函数,每一个构造函数当产生时,首先内存中会给它分配一个空间,然后有一个叫Fn的变量指向它,比如下图中,变量Fn中存的是地址0x123指向内存中Fn函数,对于内存中的Fn解析器都会给它添加一个属性叫prototype,这个属性存的是一个地址值,它指向一个空的object对象,然后是用户添加的一个叫test1的方法

    在这里插入图片描述

    接着我们执行

    
    function Fn(){
    	this.test1=function (){
    		console.log('test1')
    	}
    }
    Fn.prototype.test2=function(){
        console.log('test2')
    }
    

    这里是指给Fn的原型对象添加一个方法为test2,也就是给这个object空对象添加一个方法test2,这个在下图已经体现,这里我们着重看另一个知识点,这个空的object对象是怎么来的,其实是通过object=new Object()产生的,那么这个空object也是一个实例对象,那前面咱们说了实例对象都有隐式原型,那么这个object也要有隐式原型,这里就涉及到一个非常重要的一句话, 实例对象的隐式原型__proto__存的也是一个地址,它指向构造它的构造函数的显式原型所指向的对象。这句话初看非常晕,我们来看这个例子object=new Object(),object是一个实例对象,它是谁构造出来的,是Object()这个函数构造出来,也就是在解析器内部会有这么一个构造函数function Object(){},那么这个Object是一个构造函数,既然是构造函数,就一定有prototype属性,它指向的是Object的原型,所以object空对象的__proto__也指向0x345,这里会有疑问,那么这个Object的原型是不是也是一个空object对象,当然不是,Object的原型就是一切的祖先,他的__proto__是null,它里面已经有解析器给我们封装好的方法比如tostring(),这也就是为什么我们任何对象都能够随时调用toString()f方法的原因,我们通过图进一步来看

    在这里插入图片描述

    这里明白以后我们接着往下看代码

    function Fn(){
    	this.test1=function (){
    		console.log('test1')
    	}
    }
    Fn.prototype.test2=function(){
        console.log('test2')
    }
    var fn=new Fn()
    

    这里我们想一想,是不是新建了一个实例对象fn,那么第一步是不是在内存为这个实例对象开辟空间,并创建一个fn的变量指向它,再来想这个fn对象是Fn这个构造函数创造的,那么它会同时拥有Fn的内部函数test1,同时fn是不是会有一个隐式原型属性(proto),里面存的地址值指向构造它的函数Fn的显式原型对象(prototype)所指向的值,来我们把图画出来

    在这里插入图片描述

    好了我们的图已经画完了,其实总结下来就是两条,1是构造函数自动会有显式原型prototype,而由构造函数new出来的实例对象会有隐式原型proto,2就是理解隐式原型存的地址值是构造出来它的构造函数的显式原型指向的地址,理解了这两句话就OK了,接下来我们到了检验的时候

    function Fn(){
    	this.test1=function (){
    		console.log('test1')
    	}
    }
    Fn.prototype.test2=function(){
        console.log('test2')
    }
    var fn=new Fn()
    fn.test1()
    fn.test2()
    fn.toString()
    fn.test3()
    

    我们一个一个来看,第一个fn.test1()很好理解,他自身就有的,接着就是另外一个知识点,解析器找属性和方法会先在自身的作用域找,如果没有,会沿着隐式原型一层层往上找,直到祖先Object的原型为止,那么我们来看fn.test2(),它首先在自身中找,没有,所以沿着proto往上找,找到了那个空object对象,在里面找到了test2,所以执行,fn.toString()是继续往上找,在祖先中找到了toString()方法,最后fn.test3()我们一路找上去,一直到祖先中也没有找到,所以返回undefind,这就是解析器查找的顺序,有没有清晰很多!


    三.高级篇

    在理解了上面的以后我们来看一个特殊的,就像刚开始所说,每一个构造函数都有显式原型,比如我们的Fn()和Object(),但是我们进一步思考,这个Fn和Object构造函数是怎么来的呢,不可能是浏览器凭空造出来的呀,其实答案就是,我们在写构造函数比如fnnction Fn(){},其实这个代码就等同于 var Fn=new Function(),以这样的形式创造出来,这么一看,好像Fn又成了一个Function的实例对象了,那Fn是不是也应该有隐式原型,指向Function的显式原型,同时Function作为构造函数也得有一个显式原型指向一个空object对象,这里我们把Fn当做Function的实例对象来画图。

    在这里插入图片描述

    其实到现在都还好理解,因为和上面聊的其实没有区别,但是套娃开始了,既然Fn是由Fn=new Function()出来的,那Function就也是个构造函数,它是怎么来的呢,这里就是最后一个知识点其实Function是new自己出来的,也就是Function=new Function()出来的,所以注意,Function的隐式原型和显式原型指向的是一个,也就是它的隐式原型等于他自身的显式原型,都是这个object空对象.这里有点绕,但是一定要理解。然后我们再来看看另外一个Object()构造函数,显然,他也是Object=new Function()出来的,所以Object()构造函数的隐式原型指向的Function的显式原型也就是这个空object对象,而这个0x234的空object对象中是不是也要有隐式原型,因为他是一个实例对象,它指向的是构造函数Object()的原型,也就是祖先,所以完全的图应该是这样。

    在这里插入图片描述

    四、总结

    那么原型和原型链有什么用呢,以后我们再想给一个实例化的对象添加方法,我们就可以把这个属性或者方法加到构造函数的显式原型那个空object对象中去,会方便不少,还有其它作用这里就不做过多解释,会在以后的博文中进一步分享。

    以上就是原型和原型链,比较绕,如果有哪里写错了,欢迎大家在评论区或者私信我及时指正,不胜感激,犹记得第一次学的时候饶了好久,但是绕出来后就会柳暗花明又一村了。加油!今天的总结就到这里,感谢大家的浏览,希望对您有所帮助!

    展开全文
  • prototype属性返回对象的所有属性方法,所有 JavaScript 内部对象都有只读的 prototype 属性,可以向其原型中动态添加属性方法,但该对象不能被赋予不同的原型。但是自定义的对象可以被赋给新的原型。 对象分为...

    原型

    JavaScript是一种基于对象的语言,JavaScript中的所有对象,都具有prototype属性。prototype属性返回对象的所有属性和方法,所有 JavaScript 内部对象都有只读的 prototype 属性,可以向其原型中动态添加属性和方法,但该对象不能被赋予不同的原型。但是自定义的对象可以被赋给新的原型。

    对象分为函数对象和普通对象,区分:凡是通过 new Function() 创建的对象都是函数对象,其他的都是普通对象。(Object ,Function 是JS自带的函数对象)

    原型对象:prototype

    在JS 中,函数对象其中一个属性:原型对象 prototype。普通对象是没有prototype属性,但有__proto__属性。

    原型的作用就是给这个类的每一个对象都添加一个统一的方法,在原型中定义的方法和属性都是被所以实例对象所共享。

    var person = function(name){
          this.name = name
       };
       person.prototype.getName = function(){//通过person.prototype设置函数对象属性
            return this.name; 
       }
       var zxj= new person(‘zhangxiaojie’);
        zxj.getName(); //zhangxiaojie       //zxj继承上属性
    

    原型链

    proto:js创建对象的内置属性,用于指向创建它的函数对象的原型对象prototype。(是JS内部使用寻找原型链的属性。当实例化一个对象时候,内部会新建一个__proto__属性并把prototype赋值给它)
    当我们实例一个对象之后,调用它的内部方法,他的运行顺序是先找自身有没有该方法,如果没有就会通过__proto__属性向上层(父级)寻找,一直寻找到Object对象中,如果还没有才会报错null

    p.proto----->Persion.proto---->object.proto----->null

    原型链之间的关系

    原型对象的属性和方法,能被实例所访问到
    每一个构造函数都有一个原型对象
    每一个原型对象都有一个指针 constructor 指向构造函数
    每一个实例都有一个内部指针(proto) 指向原型对象

    原型链上的属性和方法能够被实例所访问到
    函数都有prototype, 实例有__proto__
    将其他类型转换成字符串时,默认会调用toString方法,这个方法是顶层原型对象上的方法,可以改写
    改写之后,转换的结果以改写结果为准

    展开全文
  • 这篇文章主要介绍了 JavaScript 中原型和原型链详解 ,本文讲解了私有变量函数 静态 变量函数实例变量函数原型和原型链的基本概念 ,需要的朋友可以参考下 javascript 中的每个对象都有一个内置的属性 prototype...
  • js中原型和原型链

    2020-09-20 10:51:02
    1.创建一个没有原型的对象: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <...

    1.创建一个没有原型的对象: 

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style> 
        .error{
            border:1px solid red;
        }
        </style>
    </head>
    
    <body>
       
    </body>
    
    </html>
    <script>
      let newObj=Object.create(null,{
          name:{
              value:'阿旭'
          }
      })
      //null是新创建对象的原型对象。
      console.log(newObj);
      /* {name:'阿旭'} 没有原型属性和方法*/
    </script>

    2.原型链

     let hd=new Object();
      Object.prototype.show=function(){
          console.log('jj')
      }
      function getName(){
    
      }
      console.dir(getName)
      console.log(getName.prototype.__proto__==getName.__proto__.__proto__)//true
      console.log(getName.prototype.__proto__==Object.prototype)//true
      let str={name:'str'};
      let a={name:'a'}
      console.log(str.__proto__==Object.prototype);//true
      console.log(Object.setPrototypeOf(str,a));//设置str原型为a
      console.log(Object.getPrototypeOf(str)==a);//true
    
    function User(name){
        this.name=name
    }
    let j=new User('yang')
    console.log(j.__proto__==User.prototype)//true
    console.log(j)
    //isPrototypeOf 判断原型
    let aB={};
    let b={};
    Object.setPrototypeOf(aB,b);//设置aB的原型b
    console.log(b.isPrototypeOf(aB));//true  判断b是不是aB的原型
    
    //属性的检测
    let a1={
        url:'baidu.com'
    }
    let b_name={
        name:'zhangsan'
    }
    Object.setPrototypeOf(a1,b_name);//
    //检测name是不是a1的属性  返回布尔值
    console.log('name' in a1)  //继承 true
    for(let key in a1){
        //hasOwnPrototy只检测当前的对象中是否含有某个属性不会检测原型的上面
       if(a1.hasOwnProperty(key)){
         console.log(key);//
       }
    }
    
    //使用call/apply借用原型链 
    //求最大值
    
    let arr=[11,2,31,14,5,33,20,4,90];
    let maxArr={
        data:[12,3,4,5]
    }
    Object.setPrototypeOf(arr,{
        max(data){
          return data.sort((a,b)=>b-a)[0]
        }
    })
    let newArr={
        lessons:{js:71,php:62,node:99,linux:88}
    }
    console.log(arr.max.call(null,Object.values(newArr.lessons)));//99
    
    //优化之后的code
    console.log(Math.max.call(null,...maxArr.data));//12
    console.log(Math.max.apply(null,Object.values(newArr.lessons)));//99

    3.dom中使用原型方法

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    <body>
        <button class="red">保存</button>
        <button>取消</button>
    </body>
    </html>
    <script>
    let dom=document.querySelectorAll('button');
    console.log(dom);//NodeList(2) [button.red, button]
    let arr=Array.prototype.filter.call(dom,(item)=>{
      return item.hasAttribute('class')
    });
    /*
        //等价于上面的
        let arr=[].filter.call(dom,(item)=>{
        return item.hasAttribute('class')
        }); 
    */
    console.log(arr);//[button.red]
    console.log(arr[0].innerHTML);//保存
    </script>

    4.使用父类构造函数初始属性

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
    </head>
    
    <body>
        <button class="red">保存</button>
        <button>取消</button>
    </body>
    
    </html>
    <script>
        //使用父类构造函数初始属性
       function User(name,age){
           this.name=name;
           this.age=age;
       }
       User.prototype.show=function(){
           console.log(this.name,this.age);
       }
       function Admin(...arg){
               User.apply(this,arg); 
       }
       Admin.prototype=Object.create(User.prototype);
       let obj=new Admin('yang',12);
       obj.show();//yang 12
       function Member(...arg){
               User.apply(this,arg); 
       }
       Member.prototype=Object.create(User.prototype);
       let obj1=new Member('zhangsa',18);
       obj1.show();//zhangsan 18
    </script>

     

    展开全文
  • 一、javascript中的原型对象prototype (http://www.zymseo.com/298.html) 首先prototype是一个属性,同时也是一个对象。其实javascript中所有函数都有prototype这个属性,反过来所有具有prototype的对象本身也是...

    一、javascript中的原型对象prototype  (http://www.zymseo.com/298.html)

                       首先prototype是一个属性,同时也是一个对象。其实javascript中所有函数都有prototype这个属性,反过来所有具有prototype的对象本身也是一个函数。   原型的作用就是给该类的每一个对象添加一个统一的方法。

                        在javascript中,构造函数也是一个对象,所以它也有对象指针。

    例如:        console.log(Person.__proto__ === Function.prototype);   //true

    二、__proto__和原型链

    __proto__是一个原型指针(隐藏的链接),它指向的是实例对象的构造函数的prototype;

    例如:         function Person(){ }

                var person = new Person();

                console.log(person.__proto__ === Person.prototype)   //true

                console.log(Person.prototype.__proto__)  //Object

                console.log(person.__proto__ .__proto__)  //Object

                console.log(Person.prototype.__proto__ == person.__proto__ .__proto__)  //true

                console.log(person.__proto__.__proto__.__proto__)  //null

               *说明:所以说javascript中的对象,追根溯源都是来自一个null对象。

               

    除了使用.__proto__方式访问对象的原型,还可以通过Object.getPrototypeOf方法来获取对象的原型,以及通过Object.setPrototypeOf方法来重写对象的原型 。

    值得注意的是,按照语言标准,__proto__属性只有浏览器才需要部署,其他环境可以没有这个属性,而且前后的两根下划线,表示它本质是一个内部属性,不应该对使用者暴露。因此,应该尽量少用这个属性,而是用Object.getPrototypeof和Object.setPrototypeOf,进行原型对象的读写操作。

    原型链:  有限的实例对象和原型之间组成有限的链。  用来实现共享属性和继承。





    展开全文
  • JS 中原型和原型链

    2019-05-29 11:46:15
    而b的原型其实就是Object的实例,所以a的实例对象,就可以通过原型链和object的prototype链接起来。 function a(){} function b(){} var b1 = new b(); a.prototype = b1; var a1 = new a(); console.log(a1.__...
  • javaScript中原型和原型链的分析深究
  • JavaScript中原型和原型链(图解)

    千次阅读 2019-11-16 15:47:54
    JavaScript中原型和原型链 用构造函数创建一个对象 function Person(){ this.age = '18'; } let person1 = new Person(); Person.prototype.name = 'zsl'; console.log(person1.name); //zsl console....
  • 原型和原型链解析 在JavaScript中,万物皆对象,分为普通对象函数对象两部分。 const obj_1 = {}; const obj_2 = new Object(); function fun_1(); const f2 = function fun_2(){}; const f3 = new Function(); ...
  • 前言:在微信公众号前端大全上看过《js中原型和原型链的深入理解》,个人认为这是我看过的js原型链的文章中,在思维结构上理解最清楚的一个文章了,本着温故而知新,有害怕找不到这个文章,我就把文章中的重要的...
  • prototype, 是一个js对象,存在于JavaScript中构造函数中。 任何JS对象都有__proto__属性,它永远指向它构造函数的原型prototype。 实例化后的对象.__proto__ === 构造函数.prototype // true 同理, 构造函数....
  • 一、先来说说栈内存堆内存 概念     堆栈都是运行时内存中分配的一个数据区,因此也被称为堆区栈区,     但二者存储的数据类型处理速度不同。 堆(heap)     队列优先,先进先出。用于复杂...
  • js中很重要的一个方面便是原型和原型链首先提出我的小疑问,原型是什么,原型链又是什么?为什么要有他们?他们用在何处?JavaScript是面向对象的语言,那么要实现面向对象,就要实现--面向对象的三大特性(封装、...
  • 对于js中的原型以及原型链,笔者一直觉得有些迷惑,对于其中的概念是大致理解的,但是如果让笔者说出来就感觉比较难以清晰的表达出来,所以就在这里做一下总结,有疑问的时候再翻出来回顾一下 首先,我们看一段...
  • console.log(typeof Function.prototype) // function console.log(typeof Object.prototype) // object console.log(typeof Number.prototype) // object console.log(typeof Boolean.prototype) // object ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,130
精华内容 452
关键字:

js中原型和原型链