原型和作用域

5 篇文章 0 订阅

原型

原型相关的东西

  1. 每个函数都有一个显式原型属性: prototype
  2. 每个实例都有一个隐式原型属性: proto
  3. 对象的隐式原型的值 = 其对应构造函数的显式原型的值.
  4. 原型对象:
    – prototype和__proto__是属性, 不是原型对象.
    – 每个函数都有一个prototype属性(显式原型属性), 它默认指向一个Object空对象, 即 原型对象.
    – 原型对象中有一个constructor属性, 它指向函数对象.
    – 每个实例对象都有一个__proto__属性(隐式原型属性).

原型链

  1. 相关内容:
    – 原型链是从对象的__proto__开始的
    – 查找属性会顺着原型链找;设置属性值不会顺着原型链
    – __proto__的作用是继承或者找方法(比如调用bind,call,apply)
    原型链
    查找对象上属性的流程: 比如: a.b
    步骤:
    先看a是否在作用域链上(一直找到window), 如果不存在, 就会报错; 如果存在, 则会判断a的类型 --> 如果a是基本类型, 则报错 --> 如果a是地址值, 则会解析b, 查找b属性 --> 查找b属性, 先在自身找, 找到了返回; 如果没有找到, 就顺着原型链找, 找到了返回, 没找到返回undefined.
    总结: 查找属性, 则会顺着原型链找.
    设置对象上属性值不会顺着原型链 ( 区别上面的 ) (如下代码)
    在这里插入图片描述

  2. 简单版的原型链:
    构造器

在这里插入图片描述
在这里插入图片描述
prototype的方法可以共用

instanceof() 方法

js基本数据类型

  1. A instanceof B --> 判断A是否是B的实例 (instanceof不能用来判断基本数据类型) --> A是实例对象, B是构造函数
  2. 返回值是 true 或者 false .

继承(看之前的笔记)

作用域

作用域相关的东西(包括了作用域链)

  1. 作用域分类: 全局作用域; 函数作用域; 块级作用域 (ES6新增的: const / let)
  2. 作用域链: 多个嵌套的作用域形成的由内向外的结构, 用于查找变量.
  3. 变量声明提升 与 函数声明提升 :
    变量提升: 在变量定义语义之前, 就可以访问到这个变量;
    函数声明提升: 在函数定义语义之前, 就执行函数;
    原因: 简单来说就是执行全局代码和函数前会进行预解析/处理 (也就是, 将var变量声明放在最前面执行; 将function函数声明放在最前面执行);
  4. 声明提升(顺序):
    a) 形参;
    b) 函数(当形参和函数同名时, 可以覆盖形参)
    c) 变量(当变量与形参和函数同名时, 不可以覆盖形参和函数, 但是可以重新赋值)
    注意事项: 函数表达式和函数构造器声明的函数不会被提升
    var是在函数作用域中声明变量的; let / const是在块级作用域声明变量的; 如果想在块级作用域中声明函数, 则使用函数表达式.
    例子:
        /* 
            第一个声明提升:
                1.形参 -- a:1,b:2
                2.函数:function a(),函数名a与形参名a重复了,则函数会覆盖形参
                3.console.log(a) 是 function.
        */
        //第一个   
        function fn(a, b) {
            console.log(a); //function
            function a() {}
        }
        fn(1, 2)
        /* 
            第二个声明提升:虽然函数优先提升,变量后提升,但是变量提升如果有重名,则不允许覆盖已有的形参或函数
                1.没有形参
                2.函数:function a()
                3.变量:a 
                4.console.log(a) 是 function ---变量不可以覆盖函数和形参
                5.变量:a=1(给变量a赋值了)
                6.console.log(a) 是 1
        */
        //第二个      
        function fn() {
            console.log(a); //function
            var a = 1;
            console.log(a); //1
            function a() {}
        }
        fn()
        /* 
            第三个声明提升:
                1.形参 -- a:1
                2.变量 -- a
                3.console.log(a) 是 1 (这里是因为变量不能覆盖形参)
        */
        //第三个
        function fn(a) {
            //虽然变量后提升,但是不能覆盖同名形参
            console.log(a); //1
            var a = 2;
        }
        fn(1)

        /* //区别上面的代码(上面的代码形参赋值),而下面这个代码形参没有赋值
         function fn(a) {
             //虽然定义了一个形参,但是形参没有赋值
             //虽然变量后提升,但是不能覆盖同名形参
             console.log(a); //undefind
             var a = 2;
         }
         fn() */
        /* 
            第四个声明提升:
                1.形参:a:1
                2.变量:a
                3.console.log(a) 是 1
                4.变量赋值:a=2
                5.console.log(a) 是 2
        */
        //第四个
        function fn1(a) {
            console.log(a); //1
            var a = 2;
            console.log(a); //2
        }
        fn1(1);
        /* 
            第五个声明提升:
                1.形参:a(没有赋值)
                2.变量:a
                3.console.log(a) 是 undefined(检测的是形参)
                4.变量赋值:a=2
                5.console.log(a) 是 2
        */
        //第五个
        function fn1(a) {
            console.log(a); //undefined
            var a = 2;
            console.log(a); //2
        }
        fn1();
        /* 
            第六个声明提升:
                1.没有形参
                2.函数function foo() {}
                3.变量foo(变量不会影响函数)
                4.console.log(foo) 是 function
                5.变量赋值foo=1
        */
        //第六个     
        function fn2() {
            console.log(foo); //function
            function foo() {}
            var foo = 1;
        }
        fn2();

        /* 
            第七个声明提升:
                1.全局函数:function a() {}
                2.变量a
                3.console.log(typeof a) 是 function(检测的是函数)
         */      
        //第七个
        function a() {}
        var a ;
        console.log(typeof a)  //function 
        /* 
            第八个声明变量: 
                1.这里是块级作用域
                2.变量b会得到提升
                3.(b in window)是true
                4.(!(b in window))是false
                5.因为是false,所以if语句不会执行,则b不能被赋值
                6.console.log(b)是undefined
        */
        //第八个   
        if (!(b in window)) {
            var b = 1;
        }
        console.log(b); //undefined 
        /* 
            第九个声明提升:
                1.函数:function c(c)
                2.变量:c (注意:虽然变量声明会被函数声明所覆盖,但是可以重新赋值)
                3.变量赋值 c=1,则此时同名的c已经被重新赋值了,由函数变成了数值
                4.c(2) 是 c is not a function (c已经变成了数值,所以不是函数了,没办法调用)
        */
        //第九个          
        var c = 1 ;
        function c(c) {
            console.log(c); 
            var c = 3;
        }
        c(2);  //c is not a function 
        var b = 1;
        function fn() {
            var b = 2;
            console.log(b); //2(先在局部作用域找,再在全局作用域找)
        }
        b = 3;
        fn();

在这里插入图片描述

this指向(看之前的笔记)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值