❤~函数

177 阅读3分钟

想到哪写哪,函数的一些balabala

函数的作用域

在js中,只有全局作用域与函数作用域的分别,当函数内部使用某个值得时候,会现在当前作用域,也就是与使用位置共存在同一个函数范围内的值,如果在当前范围内没有找到,就会向外扩展一层,在外部第一层包裹的函数内部进行查找,如果仍未找到,继续向外查找,直到找到最外层的window全局作用域

函数的变量值

首先是最基本的,单个函数在使用数据时,变量的值就是距离调用处最近位置的值,可以是内部的

function fun(){
    let n = 1;
    console.log(n)         //1
}

或者在外部

let n = 1;
function fun(){
    console.log(n)        //1
}

当有多层函数嵌套的层级关系时,会在作用域链上进行查找

function funout(){
    let n = 1;
    function funin(){
        console.log(n)        //1
    }
}

那么,当嵌套结构的内层函数,作为返回值时,输出的n值会变成什么?

let n = 10;
function funout(){
    let n = 1;
    function funin(){
        console.log(n)
    }
    return funin;
}

let x = funout();
x();        //1?10
  • 在调用x的时候,相当于在调用里层的funin函数,函数使用变量的值只与它初始的位置有关, console.log(n)的初始位置中,能访问到作用域链是包括函数自身和外层funout以及最外层的window,根据由里向外的顺序,在funout层就能找到n的值,停止查找.因此最终的输出结果是1;

函数的this指向

与值不同的是,函数的this在定义时不会有明确的指向,只有函数在被调用时,才能知道this指向谁,如果是单纯的调用func相当于window.func,默认的被全局调用,this的指向是window,而当作为方法或new时,指向的是对象或实例化的结果.

如果是箭头函数,内部没有this指针,会根据调用时的作用域链,向外查找,直到找到有明确的this指向位置,并将自己的this指向于该指向保持一致.

函数的闭包

可以访问到本不在自身作用域范围内的值

function g(){
    let i = 1;
    return function(){
        return i+1;
    }
}
let res = g();
res();//2

正常情况下,res身上只有window这一个全局作用域,没有办法获取到g()内部的值,但通过返回函数,使res能获取到i的值,这种情况被称作闭包;

原型

任何引用类型上,都有一个隐式的__proto__属性,指向创建这个内容的对象;

let obj = {};
//等价↑↓   obj是通过Object创建出来的
let obj = new Object();

obj上会有一个__proto__指向创建它的那个对象,也就是Object的原型prototype;

任何函数身上都会有一个prototype属性,包括了自身的一些方法,prototype本身又是一个对象结构,所以它的身上也会有指向创建自己的__proto__;

因为构造出来的实例对象的__proto__指向了prototype,所以可以通过这个指向关系,搭建出一个关系结构,当对象需要一些自己身上没有的属性或方法时,会沿着这条关系结构向上进行查找,产生找到停止/未找到报错两个结果;这条链式结构并不是无限延长的,它的终点是Object,这个对象是js里一切对象的根源,而它自身的根源是null;

这也是我们在js中伪装继承的一种方法,通过链式结构实现向上查找方法共享的继承模式;

---------各有各的写法-------
function P(){}
function C(){
    P.call(C);
    C.prototype = Object.create(P.prototype);
    C.prototype.constructor = C;
}
ES6----------语法糖
class P{}
class C extends P{
    constructor(a,b){
        super(a);
        this.b = b;
    }
    geta(){
        ///////
    }
}