-
2016-10-13 15:56:22
原型和原型链,作用域链区别:
在JavaScript中,一共有两种类型的值,原始值和对象值.每个对象都有一个内部属性[[prototype]],我们通常称之为原型.原型的值可以是一个对象,也可以是null.如果它的值是一个对象,则这个对象也一定有自己的原型.这样就形成了一条线性的链,我们称之为原型链(比如我们新建一个数组,数组的方法就是从数组的原型上继承而来的)
一般来说,作用域链是针对变量的,js里面大的范围上来说,只有两种作用域,全局作用域和函数内部作用域,如果函数1里面又定义了函数2(一般都是匿名函数), 那么就有了这么一个作用域链全局作用域==>函数1作用域==>函数2作用域;特点是函数1里面可以直接使用全局作用域的变量,函数2里面可以直接使用全局作用域和函数1作用域的变量 原型链的话,一般是定义构造函数时用到,可以认为是针对构造函数的或者说针对构造函数对应的类的;原型链的头部就是Object类/构造函数,如果有构造函数1.prototype = 构造函数2;那么也就有这么一个原型链; Object ==> 构造函数1 ==> 构造函数2,这样的好处是构造函数2对应的类,可以拥有构造函数1 和Object中的属性,js没有对应继承的关键字,所以用原型链来模拟继承的效果。
原型:
原型继承:<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>原型</title> </head> <body> <script> //js所有函数都有一个prototype属性,这个属性引用了一个对象,即原型对象,也简称为原型 function CreateDog(name,color){ this.name = name; this.color = color; } //prototype 作用是 扩展了方法对象的属性 CreateDog.prototype.swiming = function (){ console.log(this.name + '在游泳'); }; var dog1 = new CreateDog('泰迪','棕色'); dog1.swiming(); var dog2 = new CreateDog('萨摩耶','白色'); dog2.swiming(); //判断一下dog1 是不是由CreateDog 构造出来 //instanceof 运算符 可以用来判断对象的类型,更重要的 可以在继承关系中判断一个实例是否是属于他的父类型 console.log(dog1 instanceof CreateDog); </script> </body> </html>
<span style="font-size:14px;"> <script> function Animal(name){ this.name = name; } Animal.prototype.say = function(){ console.log('呜呜呜呜呜呜'); } var animal1 = new Animal('猫'); //animal1.say(); //function对 有没有“叫”的功能 function Dog(dogName){ this.dogName = dogName; } //继承 Dog.prototype = Object.create(Animal.prototype); //Dog.prototype = animal1; var dog1 = new Dog('泰迪'); dog1.say(); </script></span>
原型链:
<script> //原型链 是一个链条的 形式,可以把对象串联起来 function CreateDog(name,color){ this.name = name; this.color = color; } CreateDog.prototype.call = function(){ console.log(this.color + this.name + '在叫!'); }; var dog = new CreateDog('萨摩耶','白色'); dog.call(); //访问原型的方法 //1.通过构造函数来访问 //console.log(CreateDog.prototype); //2. 通过实例化的对象来访问 //console.log(dog.__proto__); //js 在创建对象(任何对象,普通对象和函数对象)的时候,都有一个__proto__的属性, //这个属性用于指向创建他的函数对象的原型对象prototype console.log(dog.__proto__ === CreateDog.prototype); //同样的,CreateDog.prototype 对象也有一个__proto__ 指向创建他的函数的原型对象 (object)的prototype console.log(CreateDog.prototype.__proto__ === Object.prototype); //Object.prototype 也有一个__proto__ 指向null console.log(Object.prototype.__proto__ === null); //原型链 特点是:__proto__ 属性, </script>
更多相关内容 -
JavaScript作用域、闭包、对象与原型链概念及用法实例总结
2020-10-18 04:39:47主要介绍了JavaScript作用域、闭包、对象与原型链,结合实例形式总结分析了javascript中变量与函数的作用域、闭包、对象、原形链相关概念、用法及注意事项,需要的朋友可以参考下 -
深入理解js原型链和作用域链,了解作用域链和原型链的区别
2020-09-05 19:15:10深入理解js原型链和作用域链,了解作用域链和原型链的区别一、原型链二、作用域链三、原型链和作用域链的区别:总结 一、原型链 每一个构造函数都有一个prototype属性,这个属性就叫原型对象。 每一个构造函数new...深入理解js原型链和作用域链,了解作用域链和原型链的区别
一、原型链
每一个构造函数都有一个prototype属性,这个属性就叫原型对象。
每一个构造函数new出来的对象都有一个–proto–属性,这个属性指向原型对象。
<script> function Car(){ //实例属性: //this.produce = ‘chevrolet‘, this.price = 8800000; } //原型属性: Car.prototype.produce = "BMW"; var chevrolet = new Car(); console.log(chevrolet.produce,chevrolet.price);//BMW 8800000 console.log(chevrolet==Car.prototype);//false; 构造函数new出来的对象和构造函数的原型对象不是同一个对象。 console.log(chevrolet.produce==Car.prototype.produce);//true; /*构造函数new出来的对象和构造函数的原型对象不是同一个对象,为什么构造函数new出来的对象能获取到构造函数原型对象的 属性:因为每一个构造函数new出来的对象都有一个--protot--原型链,该原型链可以把new出来的对象和原型对象连接在一起。 */ </script>
<script> // function Car(){ // //实例属性: // this.produce = ‘chevrolet‘, // this.price = 8800000; // } // var chevrolet = new Car(); // console.log(chevrolet.produce,chevrolet.price);//chevrolet 8800000 // function Car(){ // //实例属性: // // this.produce = ‘chevrolet‘, // this.price = 8800000; // } // //原型属性: // Car.prototype.produce = "BMW";//prototype相对于构造函数而言,写法:构造函数名.prototype.属性 // var chevrolet = new Car(); // console.log(chevrolet.produce,chevrolet.price);//BMW 8800000 // function Car(){ // //实例属性: // this.produce = ‘chevrolet‘, // this.price = 8800000; // } // //原型属性: // Car.prototype.produce = "BMW"; // var chevrolet = new Car(); // console.log(chevrolet.produce,chevrolet.price);//chevrolet 8800000 原型链的解析过程:先找实例属性,再找原型属性。 function Car(){ //实例属性: //this.produce = ‘chevrolet‘, this.price = 8800000; } //原型属性: // Car.prototype.produce = "BMW"; var chevrolet = new Car(); Object.prototype.produce = ‘Audi‘; console.log(chevrolet.produce,chevrolet.price);//Audi 8800000 //原型链的解析过程:先找实例属性,再找原型属性,若实例属性和原型属性都不存在,则找Object的原型属性。 </script>
二、作用域链
全局作用域、局部作用域。
<script> var num = 10; function fn(num){ num = 20; } fn(); console.log(num);//10 //向上查找,在函数体内找到同样的变量,操作的就是局部,否则是全局。 //题解:1.找var,fn-->2.逐行解析代码:全局变量num;遇到函数跳过;调用函数,解析函数体:变量num向上查找,在函数体内 //找到形参num,所以此处num是局部变量,因此输出结果为全局变量num=10。 </script>
<script> var num = 10; function fn(){ num = 20; } fn(); console.log(num);//20 //题解:1.找var,fn——>2.逐行解析代码:全局变量num;遇到函数跳过;调用函数,解析函数体:变量num向上查找,在函数体内 //没有找到num,继续在全局范围内找,找到全局变量num,并将num=20赋值于全局变量,因此输出结果为全局变量num=20。 </script>
<script> var num = 10; function fn(){ var num = 20;//在函数体内部使用var明确定义的变量是私有变量。 } fn(); console.log(num);//10 //题解:函数调用后,函数体内的变量会被销毁,所以输出结果10。 </script>
三、原型链和作用域链的区别:
原型链:原型链作用在构造函数上,原型链操作的是构造函数的属性:实例属性和原型属性;
作用域链:作用域链作用域普通函数上,操作的是全局变量和局部变量。
总结
good afternoon -
什么是原型链和作用域链?
2022-05-01 23:52:191.作用域链 2.原型链 1.作用域链 JavaScript 在执⾏过程中会创建一个个的可执⾏上下⽂。 (每个函数执行都会创建这么一个可执行上下文) 每个可执⾏上下⽂的词法环境中包含了对外部词法环境的引⽤,可通过该...目录
1.作用域链
JavaScript 在执⾏过程中会创建一个个的可执⾏上下⽂。 (每个函数执行都会创建这么一个可执行上下文)
每个可执⾏上下⽂的词法环境中包含了对外部词法环境的引⽤,可通过该引⽤来获取外部词法环境中的变量和声明等。
这些引⽤串联起来,⼀直指向全局的词法环境,形成一个链式结构,被称为作⽤域链。
简而言之: 函数内部 可以访问到 函数外部作用域的变量, 而外部函数还可以访问到全局作用域的变量,
这样的变量作用域访问的链式结构, 被称之为作用域链
let num = 1 function fn () { let a = 100 function inner () { console.log(a) console.log(num) } inner() } fn()
下图为由多个可执行上下文组成的调用栈:
-
栈最底部为
全局可执行上下文
-
全局可执行上下文
之上有多个函数可执行上下文
-
每个可执行上下文中包含了指向外部其他可执行上下文的引用,直到
全局可执行上下文
时它指向null
js全局有全局可执行上下文, 每个函数调用时, 有着函数的可执行上下文, 会入js调用栈
每个可执行上下文, 都有者对于外部上下文词法作用域的引用, 外部上下文也有着对于再外部的上下文词法作用域的引用
=> 就形成了作用域链
2.原型链
要讲清楚这个问题,主要着重这几个方面:
-
什么是原型对象
-
构造函数, 原型对象, 实例的三角关系图
-
原型链如何形成
原型对象
在 JavaScript 中,除去一部分内建函数,绝大多数的函数都会包含有一个叫做
prototype
的属性,指向原型对象,基于构造函数创建出来的实例, 都可以共享访问原型对象的属性。
例如我们的
hasOwnProperty
,toString
⽅法等其实是 Obejct 原型对象的方法,它可以被任何对象当做⾃⼰的⽅法来使⽤。hasOwnProperty
用于判断, 某个属性, 是不是自己的 (还是原型链上的)来看一段代码:
let person = { name: "Tom", age: 18, job: "student" } console.log(person.hasOwnProperty("name")) // true console.log(person.hasOwnProperty("hasOwnProperty")) // false console.log(Object.prototype.hasOwnProperty("hasOwnProperty")) // true
可以看到,
hasOwnProperty
并不是person
对象的属性,但是person
却能调用它。那么
person
对象是如何找到 Object 原型中的hasOwnProperty
的呢?这就要靠原型链的能力了。
原型链
在 JavaScript 中,每个对象中都有一个
__proto__
属性,这个属性指向了当前对象的构造函数的原型。对象可以通过自身的
__proto__
属性与它的构造函数的原型对象连接起来,而因为它的原型对象也有
__proto__
,因此这样就串联形成一个链式结构,也就是我们称为的原型链。 -
-
作用域链和原型链
2020-02-13 13:25:37原型链与作用域链 区别: 作用域是对于变量而言,原型链是对于对象的属性。 作用域链顶层是window,原型链顶层是Object。 联系:从链表开头寻找,直到找到为止。 二、作用域链 作用域 作用域就是变量与函数的可...一.原型链与作用域链
区别:- 作用域是对于变量而言,原型链是对于对象的属性。
- 作用域链顶层是window,原型链顶层是Object。
联系:从链表开头寻找,直到找到为止。
二、作用域链
- 作用域
作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。作用域分为全局作用域和局部作用域
全局作用域:任何地方都能访问到的对象拥有全局作用域。
局部作用域:局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所以在一些地方会把这种作用域成为函数作用域。 - 作用域链
作用域链,即当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链。
var a = 10;
function fun(){
console.log(a);
var a = 1;
var b = 20;
b++;
function fun1(){
console.log(b);
b += 6;
function fun2(){
console.log(b);
console.log(a);
}
}
console.log(a);
}
1、首先,开始执行前,创建执行环境(数组):ECS
向执行环境栈中压入第一个默认的函数main(),创建全局作用域对象Window,全局做预编译GO,函数的隐藏属性scope记录执行期上下包括自己的所属作用域的对象。如上图
2、执行开始,在执行环境中压入新的函数,创建一个活动的AO,保存函数中的局部变量,当自己的AO中没有该变量,可以通AO中的parent(scope)中去寻找。
3、执行结束,执行环境中的的本次函数出栈,同时创建的活动对象AO消失。
三、原型链
- 什么是原型
每个构造函数都有一个prototype属性,这个属性指向一个对象,即原型对象。
原型对象默认拥有一个constructor属性,指向指向它的那个构造函数(也就是说构造函数和原型对象是互相指向的关系)。 - 什么是原型链
由于__proto__任何对象都具有的属性,js中一切都是对象,所以一条由__proto__形成的链条,顶端为null,即原型链。
function Student(sname, sage){
this.sname = sname;
this.sage = sage;
}
Student.prototype.intr = function(){
console.log(I'm ${this.sname},I'm ${this.sage}
);
}
var lilie = new Student(“Li Lei”, 12);
var hmm = new Student(“Han Meimei”, 12);其原型链图如下
Student.proto ==>Function.prototype
Function.prototype.constructor ==> function Function(){}
Function.prototype.proto ==>Object.prototype
Function.prototype.proto ==>Object.prototype -
原型链和作用域
2019-02-27 10:42:03原型: 每个函数(构造函数)都有一个prototype(原型)属性...原型链和作用域 作用域是针对变量的 全局作用域==>函数1作用域==>函数2作用域 var a = 1; function b(){ var a = 2; function ... -
原型与原型链,作用域与作用域链
2021-06-01 15:10:27原型与原型链: 每个函数都有 prototype 属性,除了 Function.prototype.bind() ,该属性指向原型。 每个对象都有 __proto__ 属性,指向了创建该对象的构造函数的原型。其实这个属性指 向了 [[prototype]] ,但是 ... -
5、作用域链和原型链的区别
2021-03-14 10:32:33作用域链:针对变量 原型链: 针对构造函数(对于对象的属性,方法) 形式不同 作用域链: 作用域的特点就是,先在自己的变量范围中查找,如果找不到,就会沿着作用域往上找。如: var a = 1; function b(){ var a... -
详解作用域链、原型链、闭包
2021-04-15 11:38:58文章目录一、作用域全局作用域函数作用域块级作用域补充----动态作用域this(下一篇文章会继续介绍)二、变量的作用域全局变量局部变量全局变量和局部变量的区别三、作用域链四、变量和函数的声明提升变量的声明提升... -
js 作用域链与原型链的区别
2020-04-05 15:26:44一句话,作用域链是查找是否有这个对象而原型链是查找这个对象是否有某个属性 -
JavaScript中的链(作用域链、原型链)
2020-03-19 20:48:44Js中存在两种老生常谈的链,作用域链和原型链。作用域链是为了访问变量而存在的链,原型链是访问对象的属性而存在的链。 作用域链 说到作用域链,首先来说下作用域的概念:执行代码的上下文,也可以说是变量对象,是... -
对原型 原型链 作用域链 和闭包的理解?
2022-03-01 16:14:52当我们查找特定属性的时候,我们先去这个对象里面找,如果没有的话就去它的原型对象里面找,如果还没有的话就去原型对象的原型对象找,这个操作就是被委托在整个原型链上。 闭包 闭包就是能够读取其他函数内部变量... -
原型、原型链、作用域、作用域链、闭包
2019-02-23 04:08:25相信看到题目都知道,这些都是js千年不变的面试题。 原型、原型链? 什么是原型、原型链? 原型:相当于一个模具,用来生产实例对象。 原型链:原型对象有个指针指向构造函数,实例...作用域、作用域链? 什么是作... -
JS 原型,原型链,作用域,闭包全解
2019-09-18 10:05:57每个函数都有一个作用域(window有一个全局作用域,可以把window想象成全局函数),每个函数对应有一个活动对象,函数作用域链,函数环境对象作用域链。他们并不是一直存在,而是动态创建的。 在定义新的函数时... -
Web前端面试题目JavaScript(作用域,原型。原型链,闭包,封装函数).txt
2020-07-06 20:12:27前端面试题,包含JavaScript的闭包,作用域,原型,原型链,上下文环境以及DOM,BOM封装函数深度克隆,以及一些常见的·JS问题,试题简单但是容易混淆,作为前端工程师必考题 -
作用域链与原型链的区别与联系
2017-08-01 12:52:25作用域 先来看一段代码: [javascript] view plain copy name=”lwy”; function t(){ var name=”tlwy”; function s(){ var name=”slwy”; console.log(name); } fun -
JS原型对象、原型链及其优缺点,以及原型链与作用域链的区别
2022-02-04 19:23:27文章目录前言一、原型对象的定义二、构造函数、实例、原型对象的关系关系图三、原型链四、继承五、原型继承的缺点六、作用域链七、作用域链和原型链的区别 前言 介绍 1.原型对象、原型链及其优缺点 2.原型链与作用... -
作用域/作用域链与原型/原型链
2022-03-14 10:40:18当代码在一个执行环境中执行时,会创建变量对象的一个作用域链(作用域形成的链条) 3. 原型 每当定义一个数据类型的时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据... -
js作用域链和原型链
2020-02-13 13:09:15如果要理解作用域链就要先理解作用域,所以要先明白作用域 一、作用域 作用域就是变量与函数的可访问范围 即作用域控制着变量与函数的可见性和生命周期 二、作用域分为全局作用域和局部作用域 全局作用域:代码在... -
原型对象、原型链, 作用域, 作用于链.md
2021-12-25 11:18:22原型对象、原型链, 作用域, 作用于链.md -
原型链和作用域链的区别
2020-07-22 12:11:261、作用域是对于变量而言,原型链是对于对象的属性。 2、作用域链顶层是window,原型链顶层是Object。 -
作用域、作用域链和原型、原型链的理解
2019-11-26 20:32:21一个函数在执行前,会创建一个执行期上下文对象,而作用域所存储的执行期上下文的集合,这种集合呈链式链接,我们称之为作用域链 原型 函数都有一个propotype属性,它指向一个对象,该对象称之为原型对象,即原型 ... -
作用域链与原型链
2020-02-13 16:51:37作用域链 1、什么是作用域链 当代码在一个环境中执行时,会创建变量对象的一个作用域链。 由子级作用域返回父级作用域中寻找变量,就叫做作用域链。 作用域链中的下一个变量对象来自包含环境,也叫外部环境。而再下... -
简谈JS的原型链和作用域链
2017-07-18 13:00:43谈起js的原型链和作用域链,我觉得还是和图结合起来说比较明白,手绘了一些图片,图片看起来虽然比较丑,但是结合起来理解地应该比较清楚 -
JavaScript复习,this指向、原型链、变量提升、作用域、闭包
2022-03-15 21:50:55文章目录 函数中this指向问题 原型 变量/函数 提升 全局执行上下文: 测试题 var可重复声明 作用域 闭包 更深入理解闭包的原理 闭包的作用 终极题目 ES5的继承 -
【js中this,window,原型链,作用域链总结】
2021-05-07 08:41:00它的this都是window,因此,哪怕一个函数是嵌套在一个对象的函数的函数内返回的对象的函数内,无论套路多少,只要是直接调用的方式,那this就是window,因此访问不到其他任何不在window对象和局部作用域内的顺序,如... -
原型链、函数、作用域和作用链
2020-04-15 20:52:29一、原型链 // 概念:对象都有__proto__...// 原型链的作用是实现继承 // __proto__属性是任何对象都有的属性,所以会形成一条__proto__链接起来的链条,递归访问__proto__必须最终到头,并且值为null。 // 属性查...