什么是作用域?原生链?它们的区别是什么?

var a=1;
function b(){
  var a=2;
  function c(){
    var a=3;
    console.log(a)
}
c();
}
b();//3

一、作用域链

作用域是相对于变量来说的。如

全局作用域==>函数b作用域==>函数c作用域;

作用域的特点是现在自己的变量范围中查找,如果找不到就会沿着作用域往上找。

例:执行c()时,若c中没有变量a,则会向上找,直到找到a,这个查找的过程就叫作用域链。

二、原生链

prototype    每一个函数都有这个属性,这个属性指向函数的原型对象

function Person(){
this.name=name; }
Person.prototype.name='babilong'
var person=new Person();

console.log(person.name);

函数的prototype指向一个对象,而这个对象正是调用构造函数时创建的实例的原型。

每一个对象(除null)创建的时候都有一个原型,都会从原型中继承属性。

__proto__    每一个对象都会有的属性,这个属性会指向该对象的原型

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

构造函数  每一个原型都有一个constructor属性,指向该关联的构造函数。

person.constructor===Person.prototype.constructor

person本身没有,但是它的原型Person.prototype有constructor属性。Person

④原型链

 每一个构造函数都有一个原型对象,原型对象那个都包含一个指向构造函数的指针(constructor),而实例都包含一个指向实例原型的内部指针(__proto__),这个原型对象还可以有自己的原型,以此类推,就形成了一个原型链,直到找到某个属性时。先去这个对象里找,如果没有就去原型对象里面找,如果还是没有就去原型对象的原型对象中找。

三、原型链的继承

核心:父类的实例就是子类的原型。

function Father(){
  this.name=name||"张三",
this.play=function(){};
}
//原型方法
Father.prototype.say=function(){
}

function Son(){}
//父类的实例就是子类的原型
Son.prototype=new Father();
var son =new Son();
//继承
son.play();
son.say();

优点:①子类的实例也是父类的实例

②父类新增原型方法/原型属性,子类都能访问的到。

缺点:①子类新增的方法和属性,必须在new父类()之后,不能放在构造器中。

②无法是实现多继承。

③来自原型对象的引用属性是所有实例共享的。

④创建子类实例时,无法向父类传参。


原文地址:https://www.cnblogs.com/babilong/p/13516486.html