精华内容
下载资源
问答
  • 原型与原型链: 每个函数都有 prototype 属性,除了 Function.prototype.bind() ,该属性指向原型。 每个对象都有 __proto__ 属性,指向了创建该对象的构造函数的原型。其实这个属性指 向了 [[prototype]] ,但是 ...

    原型与原型链:

    每个函数都有 prototype 属性,除了 Function.prototype.bind() ,该属性指向原型

    每个对象都有 __proto__ 属性,指向了创建该对象的构造函数的原型。其实这个属性指 向了 [[prototype]] ,但是 [[prototype]] 是内部属性,我们并不能访问到,所以使⽤ __proto__ 来访问。

    对象可以通过 __proto__ 来寻找不属于该对象的属性 __proto__ 将对象连接起来组 成了原型链

    关系: instance.constructor.prototype = instance.__proto__

    作用域与作用域链:

    作⽤域就是变量与函数的可访问范围,即作⽤域控制着变量与函数的可⻅性和⽣命周期,也可理解为该上下⽂中声明的变量和声明的作⽤范围,可分为块级作⽤域函数作⽤域

    作⽤域链可以理解成包含⾃身变量对象和上级变量对象的列表,通 过 [[Scope]] 属性查找上级变量。

    作⽤域链的作⽤是保证执⾏环境⾥有权访问的变量和函数是有序的,作⽤域链的变量只能向上访问,变量访问到 window 对象即被终⽌,作⽤域链向下访问变量是不被允许的。

    展开全文
  • 原型与原型链

    2021-03-18 11:11:33
    在JavaScript中,万物皆对象,每个对象被创建出来都有其对应的一个原型,使对象共享原型的属性方法,所以原型存在的意义就是解决属性方法共享的问题,减少不必要的内存消耗。 下面让我们来理解下几个小概念: ...

    前言

    网上有太多关于原型的资料,不是一上来就各种概念,让人看到摸不着头脑,就是贴各种代码,少个通俗的解释,所以才有了这一篇文章。

    原型

    用电影的例子来讲,电影的角色一般都会基于某个原型创建出来的,比如最近大火的《你好李焕英》原型就是贾玲的妈妈。

    在JavaScript中,万物皆对象,每个对象被创建出来都有其对应的一个原型,使对象共享原型的属性与方法,所以原型存在的意义就是解决属性与方法共享的问题,减少不必要的内存消耗。

    下面让我们来理解下几个小概念:

    prototype

    我们知道在JS中每次创建一个函数,该函数就会自动带有一个prototype属性,该属性指向函数的原型对象。

    function Person(age) {
        this.age = age       
    }
    Person.prototype.name = 'qiyue'//原型增加一个name属性
    console.log(Person.prototype) //输出原型对象 {name: 'qiyue', constructor: ƒ}
    var person1 = new Person()
    var person2 = new Person()
    console.log(person1.name) //qiyue 共享原型属性
    console.log(person2.name)  //qiyue 共享原型属性
    

    上述例子中,函数的prototype指向了一个对象,而这个对象正是调用构造函数时创建的实例的原型,也就是person1和person2的原型。

    让我们用一张图表示构造函数和实例原型之间的关系:

    _proto_

    这是js对象中(null和undefined除外)都会存在的属性,这个属性会指向该对象的原型(注意:__proto__因为浏览器兼容性问题,不一定都可以获取到,应当使用Object.getPrototypeOf函数作为获取对象原型的标准API)。

    function Person() {
    }
    var person = new Person();
    console.log(person.__proto__ === Person.prototype); // true
    

    看着上面这张图,让我们来总结下:

    1. 构造函数(Person)通过prototype属性指向实例的原型。
    2. person是基于原型Person.prototype创建出的实例,并且可以通过__proto__属性指向其原型。
    3. Person.prototype和person.__proto__都指向实例的原型。

    理解了原型的概念,下面我来理解原型链就好理解些了。

    原型链

    在JavaScript 中,每个对象通过__proto__属性指向它的原型对象,这个原型对象又有自己的原型,直到某个对象的原型为 null 为止,这种一级一级的链结构就称为原型链。

    function Person(age){
      this.age = age
    }
    Person.prototype.name = 'qiyue'
    var person = new Person();
    console.log(person.__proto__);//Person.prototype=> {name: 'qiyue', constructor: ƒ}
    console.log(person.__proto__.__proto__);//Object.prototype=>{constructor: ƒ,…}
    console.log(person.__proto__.__proto__.__proto__);//null
    

    当你用构造函数(Person)建立一个对象时,它的原型链就是:
    person ==》 Person.prototype ==》 Object.prototype ==》 null

    再来看下对象属性的搜索

    Person.prototype = {age:24};
    var person = new Person("qiyue");
    console.log(person.name);//qiyue
    console.log(person.age);//24
    

    对象属性的搜索是作用于整条原型链上的。搜索会从原型链头开始,直到原型链的末端,寻找这个属性,这个例子中name属性就在对象本身找到的(person),而age是在原型中找到的(Person.prototype)。

    运用

    instanceOf

    function instanceOf(left, right)
    {
        if (typeof left !== 'object' || left === null) return false;
        let proto = Object.getPrototypeOf(left);
        while (true)
        {   //循环往下寻找,直到找到相同的原型对象
            if (proto === null) return false;
            if (proto === right.prototype) return true;//找到相同原型对象,返回true
            proto = Object.getPrototypeOf(proto);
        }
    }
    console.log(instanceOf(person,Person));//true
    console.log(instanceOf(person,Object));//true
    console.log(instanceOf(person,Array));//false
    

    instanceOf原理就是寻找构造函数的原型(prototype)是否在这个对象的原型链上。

    继承

    function Person(){
        this.say = function (){
            console.log("hello");
        }
    }
    function Student(){
    }
    function Teacher(){
    }
    Student.prototype = new Person();
    Student.prototype.constructor = Student;
    Teacher.prototype = new Person();
    Teacher.prototype.constructor = Teacher;
    var s = new Student();
    s.say();
    var t = new Teacher();
    t.say();
    
    

    Student需要say方法,Teacher也需要say方法,那我们可以把共有的行为通过原型继承的方式共享say方法。

    扩展原型方法

    var nums = new Array(1,2,3);
    /**添加一个返回数组的第一个元素的新方法。 */
    Array.prototype.first = function ()
    {
        return this[0];
    }
    console.log(nums.first());//1
    

    上面我们给数组原型增加了first方法,这让我们所有数组对象都会共享到这个方法。

    总结

    原型的存在是js的一个重点也是一个难点,
    通过本篇,我们了解了原型与原型链,并且也介绍了一些原型常用的运用场景来加深我们对原型与原型链的理解。

    展开全文
  • 函数,构造函数,函数原型(实例原型),实例,实例对象,对象原型原型,prototype,proto,constructor 先看下面这个例子: function Person() { } function Foo() { } const foo = new Foo(); const person = ...

    前言

    看过不少深入了解原型原型链系列,大体是明白不少,还是不够透彻!以下仅为个人总结和理解。

    初见各名词

    首先得了解这几个词:
    函数,构造函数,函数原型(实例原型),实例,实例对象,对象原型,原型,prototype,proto,constructor

    先看下面这个例子:

    function Person() {
    
    }
    function Foo() {
    
    }
    const foo = new Foo();
    const person = new Person();
    
    

    函数,构造函数:在上面的例子中构造函数就是Person

    函数原型(实例原型):后面会结合式子阐述。(我的理解是最初始的函数,他的属性所有函数使用)

    实例与实例对象:在上面的例子中,有构造函数Person、Foo,我们用new操作符实例化了foo实例对象、person实例对象

    原型对象与原型:后面会结合式子阐述。

    原型

    任何一个构造函数都会有prototype属性。打印构造函数Foo.prototype,Person.prototype你会发现

    console.log(Foo.prototype,Person.prototype);
    //{ constructor: f Foo(), __proto__: Object } { constructor: f Person(), __proto__: Object }
    

    Foo.prototype,Person.prototype它们都指向各自函数的原型对象

    a) 任何一个构造函数函数(Person,Foo),都拥有一个prototype属性,它指向这个函数的原型对象

    从打印出来的式子

    { 
      constructor: f Foo(),
      __proto__: Object 
    } 
    { 
    constructor: 
      constructor: f Person(),
      __proto__: Object 
    }
    

    不难看出 Person.prototype和Foo.prototype都有constructor和__proto__属性。

    而且Person.prototype.constructor和Foo.prototype.constructor都指向的是各自的构造函数本身。

    可以通过式子大胆验证下:

    console.log(Person.prototype.constructor === Person) // true
    console.log(Foo.prototype.constructor === Foo) // true
    

    b) 构造函数的prototype的constructor都是指向的构造函数的本身

    那么Person.prototype.__proto__和Foo.prototype.__proto__指向什么呢?

    console.log(Person.prototype.__proto__ === Object.prototype) // true
    console.log(Foo.prototype.__proto__ === Object.prototype) // true
    

    上式中的Person.prototype.__proto__和Foo.prototype.__proto__都指向Object.prototype

    c) Person.prototype的原型指向Object.prototype

    也就是说每个函数的原型都是Object的实例,那么Object.prototype的原型,new出来的foo,person的原型呢?

    console.log(foo.__proto__);//{ constructor: f Foo(), __proto__: Object } 
    console.log(person.__proto__);//{ constructor: f Person(), __proto__: Object }
    console.log(Object.prototype.__proto__);//null
    

    不难看出

    console.log(foo.__proto__===Foo.prototype);//true
    console.log(person.__proto__===Person.prototype);//true
    console.log(Object.prototype.__proto__===null);//true
    

    d) foo,person的__proto(实例的原型) === Person.prototype;因此把Person.prototype叫做实例原型。

    e) Person.prototype.proto(实例原型的原型) === Object.prototype;因此实例原型的原型指向的是Object.prototype。

    f) Object.prototype.proto(Object.prototype的原型) === null;因此Object.prototype.proto 的值为null,也就是Object.prototype没有原型。

    再上面的 b 项中式子拿下来(b.构造函数的prototype的constructor都是指向的构造函数的本身)

    console.log(Person.prototype.constructor === Person) // true
    console.log(Foo.prototype.constructor === Foo) // true
    

    那么Object.prototype.constructor是不是也是Object本身呢?

    console.log(Object.prototype.constructor===Object)//true
    

    g) Object.prototype.constructor === Object

    由此讶羽大佬的关系图也就清晰了
    原型链

    原型链

    由上面的分析,可以看出原型链实际上就是运行const foo = new Foo()语句(创建实例函数时),产生了一个链条反应,这个最顶端也就是原型链最顶端是Object.prototype.__proto__为null。

    总结:从一个实例对象往上查找构造这个实例的相关联对象(原型对象),这个关联的对象(原型对象)通过__prototo__属性再往上找创造他的原型对象,以此类推,一直往上找,直到Object.prototype的原型对象为null结束的过程。

    原型链是通过prototype的原型和__proto__的属性来完成原型链的查找。

    原型与原型链一知半解

    展开全文
  • Js高级原型与原型链

    2021-03-29 20:16:29
    1、原型定义 我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype * 这个属性对应着一个对象(默认指向一个Object空对象),这个对象就是我们所谓的原型对象 ...2、显示原型与隐式原型 ...

    1、原型定义

    我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
                 *         这个属性对应着一个对象(默认指向一个Object空对象),这个对象就是我们所谓的原型对象

      console.log(Date.prototype)
     // 原型对象中有一个属性constructor, 它指向函数对象
      console.log(Date.prototype.constructor===Date)//true

    2、显示原型与隐式原型

         每个函数function都有一个prototype,即显式原型
         每个实例对象都有一个__proto__,可称为隐式原型

    function Fn() {
    
      }
      var fn = new Fn()
      console.log(显示:Fn.prototype,隐式: fn.__proto__)
      console.log(Fn.prototype===fn.__proto__)//true
    

    二者之间的关系:相等

    3、原型链(图解)  别名: 隐式原型链

    访问一个对象的属性时,
        * 先在自身属性中查找,找到返回
        * 如果没有, 再沿着__proto__这条链向上查找, 找到返回
        * 如果最终没找到, 返回undefined

    4、属性问题

    1.读取对象的属性值时: 会自动到原型链中查找
    2. 设置对象的属性值时: 不会查找原型链, 如果当前对象中没有此属性, 直接添加此属性并设置其值
    3. 方法一般定义在原型中, 属性一般通过构造函数定义在对象本身上

     function Fn(){
       	
       }
       Fn.prototype.a ="xxx";
       var fn1 = new Fn();
       console.log(fn1.a,fn1);
       var fn2 = new Fn();
       fn2.a = "eee"
       console.log(fn2.a,fn2);

    5、变量提升与函数提升

    . 变量声明提升
      * 通过var定义(声明)的变量, 在定义语句之前就可以访问到
      * 值: undefined
    2. 函数声明提升
      * 通过function声明的函数, 在之前就可以直接调用
      * 值: 函数定义(对象)

    先预处理变量, 后预处理函数

    6、执行上下文

      1. 全局执行上下文
      * 在执行全局代码前将window确定为全局执行上下文
      * 对全局数据进行预处理
        * var定义的全局变量==>undefined, 添加为window的属性
        * function声明的全局函数==>赋值(fun), 添加为window的方法
        * this==>赋值(window)
      * 开始执行全局代码
    2. 函数执行上下文
      * 在调用函数, 准备执行函数体之前, 创建对应的函数执行上下文对象
      * 对局部数据进行预处理
        * 形参变量==>赋值(实参)==>添加为执行上下文的属性
        * arguments==>赋值(实参列表), 添加为执行上下文的属性
        * var定义的局部变量==>undefined, 添加为执行上下文的属性
        * function声明的函数 ==>赋值(fun), 添加为执行上下文的方法
        * this==>赋值(调用函数的对象)

     

     

     

    展开全文
  • Js原型与原型链详解

    2021-02-01 09:30:37
    在介绍原型原型链之前,我们有必要先复习一下构造函数的知识。 一、构造函数 构造函数模式的目的就是为了创建一个自定义类,并且创建这个类的实例。构造函数模式中拥有了类和实例的概念,并且实例和实例之间是...
  • Js 原型与原型链

    2021-01-14 17:36:41
    博主表示(我总结不出来) 不过!!! 分享个链接吧 https://juejin.cn/post/6844903797039300615 (搬运工表示)写的很好 容易懂
  • 原型与原型链的理解

    2021-03-11 10:50:24
    前言javascript语言是一种面向对象的语言,它没有"子类"和"父类"的概念,里面所有的数据类型都是对象,这一点Java非常相似。如何将这些对象联系起来呢?Brendan Eich在考虑设计继承机制的时候,参考了C++和JAVA...
  • 本文主要讲解构造函数、原型原型链的定义,以及他们之间的关系。如何通过原型对象的内部指针的形成原型链?如何检测原型原型链等。 二、原型 1、构造函数 在讲解原型前,首先需要知道什么是构造函数,先看一...
  • prototype属性指向的是一个对象,这个对象称为原型对象。 当函数作为构造函数使用,它所创建的对象中都会有一个隐含的属性执行该原型对象。 这个隐含的属性可以通过对象.__proto__来访问。 原型对象就相当于一个公共...
  • 一、原型与原型链 1.1 显示原型与隐式原型 1、显示原型 1) 每个函数都有一个prototype属性,即显示原型。它默认指向一个Object空实例对象,即原型对象。 但是Objct函数除外。 2) 函数的...
  • JS中的原型与原型链

    2021-03-10 18:47:38
    一、什么是原型 原型是Javascript中的继承的基础,JavaScript的继承就是基于原型的继承。 二、函数的原型对象 创建一个函数A(就是就是声明一个函数),那么浏览器就会在内存中创建一个对象B,而且每个函数都默认会...
  • js-es6知识汇总(1)原型与原型链 1.面向过程与面向对象 1.1面向过程 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候再一个一个的依次调用。 1.2面向对象 面向对象是把...
  • 原型与原型链的常见面试题 1. var A=function(){} A.prototype.n=1 var b=new A() A.prototype={ n:2, m:3 } var c=new A() console.log(b.n,b.m,c.n,c.m)//1,undefined,2,3 分析一下:b.n 因为b是A的实例...
  • 日期:2021年9月15日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;...文章目录一、什么是原型 一、什么是.
  • JavaScript常被描述为一种**「基于原型的语言」**——每个对象都拥有一个**「原型对象」**,对象以其原型为模板、从原型继承属性和放法。原型对象也可能拥有原型,并从中继承属性和方法,一层一层以此类推。这种...
  • 原型与原型链详解

    2020-12-23 22:11:02
    大部分面向对象语言不同,ES6之前中没有引入类 (Class) 的概念,JavaScript并非通过类而是直接通过构造函数来创建实例的。在介绍原型原型链之前,我们有必要先复习一下构造函数的知识。 一、构造函数 构造函数...
  • JS原型与原型链

    2021-09-21 14:04:56
    什么是原型 所有引用类型都有一个——proto——表示隐式原型,属性值是一个普通的对象 所有函数都有一个prototype(原型),属性值是一个普通的对象 所有引用类型——proto——属性指向 它构造函数的prototype ...
  • javascript原型与原型链

    2021-09-08 21:16:13
    每个函数都有一个prototype属性,被称为显示原型 2._ _proto_ _ 每个实例对象都会有_ _proto_ _属性,其被称为隐式原型 每一个实例对象的隐式原型_ _proto_ _属性指向自身构造函数的显式原型prototype 3. ...
  • 一、prototype在JavaScript中,每个函数都有一个prototype属性,这个属性指向函数的原型对象。例如:functionPerson(age) {this.age =age}Person.prototype.name= 'kavin'var person1 = newPerson()var person2 = ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 745,065
精华内容 298,026
关键字:

原型与