一, 原型链 (家族族谱)
概念: JS 里面的对象可能会有父对象, 父对象还会有父对象,..... 祖先
根本: 继承
属性: 对象中几乎都会有一个__proto__属性, 指向他的父对象
意义: 可以实现让该对象访问到父对象中相关属性
根对象: Object.prototype
- var arr=[1,3,5]
- arr.__proto__:Array.prototype
arr.__proto__.__proto__就是找到了根对象
- function Animal(){}
- var cat=new Animal();
- //cat.__proto__:Animal.prototype
- //cat.__proto__.__proto__: 根对象
错误的理解: 在 js 中, 万物继承自 Object? --> 在 js 中万物继承自 Object.prototype
二, 作用域
(一), 变量作用域
变量作用域的概念: 就是一个变量可以使用的范围
JS 中首先有一个最外层的作用域: 称之为全局作用域
JS 中还可以通过函数创建出一个独立的作用域, 其中函数可以嵌套, 所以作用域也可以嵌套
- var age=18; //age 是在全局作用域中声明的变量: 全局变量
- function f1(){
- console.log(name); // 可以访问到 name 变量
- var name="周董" //name 是 f1 函数内部声明的变量, 所以 name 变量的作用域就是在 f1 函数内部
- console.log(name); // 可以访问到 name 变量
- console.log(age); //age 是全局作用域中声明的, 所以 age 也可以访问
- }
- console.log(age); // 也可以访问
- //-->1 级作用域
- var gender="男";
- function fn(){
- console.log(age); // 因为 age 是在 fn 作用域内声明的
- //age:undefined: 既然有值就是可以访问
- console.log(height);//height 不是在该作用域内部声明的, 所以不能访问
- //-->2 级作用域
- return function(){
- //-->3 级作用域
- var height=180;
- }
- var age=5;
- }
- // 注意: 变量的声明和赋值是在两个不同时期的
- function fn(){
- console.log(age); //undeinfed
- var age=18;
- console.log(age); //18
- }
- //fn 函数执行的时候, 首先找到函数内部所有的变量, 函数声明, 把他们放在作用域中, 给变量一个初始值: undefined --> 变量可以访问
- // 逐条执行代码, 在执行代码的过程中, 如果有赋值语句, 对变量进行赋值
- function fn(){
- var age; // 初始值: undefined
- console.log(age); //undeinfed
- age=18; // 修改了变量的值
- console.log(age); //18
- }
(二), 作用域链
由于作用域是相对于变量而言的, 而如果存在多级作用域, 这个变量又来自于哪里? 这个问题就需要好好地探究一下了, 我们把这个变量的查找过程称之为变量的作用域链
作用域链的意义: 查找变量 (确定变量来自于哪里, 变量是否可以访问)
简单来说, 作用域链可以用以下几句话来概括:(或者说: 确定一个变量来自于哪个作用域)
查看当前作用域, 如果当前作用域声明了这个变量, 就确定结果
查找当前作用域的上级作用域, 也就是当前函数的上级函数, 看看上级函数中有没有声明
再查找上级函数的上级函数, 直到全局作用域为止
如果全局作用域中也没有, 我们就认为这个变量未声明 (xxx is not defined)
- function fn(callback){
- var age=18;
- callback()
- }
- fn(function(){
- console.log(age);
- // 分析: age 变量:
- //1, 查找当前作用域: 并没有
- //2, 查找上一级作用域: 全局作用域
- //--> 难点: 看上一级作用域, 不是看函数在哪里调用, 而是看函数在哪里编写
- //--> 因为这种特别, 我们通常会把作用域说成是: 词法作用域
- })
举例 1:
- var name="张三";
- function f1(){
- var name="abc";
- console.log(name); //abc
- }
- f1();
举例 2:
- var name="张三";
- function f1(){
- console.log(name); //underfind
- var name="abc";
- }
- f1();
举例 3:
- var name="张三";
- function f1(){
- return function(){
- console.log(name); //underfind
- }
- var name="abc";
- }
- var fn=f1();
- fn();
举例 4:
- var name="张三";
- function f1(){
- return {
- say:function(){
- console.log(name); //underfind
- var name="abc";
- }
- }
- }
- var fn=f1();
- fn.say()
来源: https://www.cnblogs.com/junjingyi/p/9191792.html