JS - 函数创建,作用域,作用域链

/**
 * 函数
 *  - 函数也是对象
 *  - 函数中可以封装一些功能(代码),在需要的时候可以执行这些功能(代码)
 *  - 使用 typeof 检查一个函数时,返回Function
 * 
 * 创建函数对象
 *  - 可以将要封装的代码以字符串的形式传递给构造函数(实际开发中不用)
 *  - 使用函数声明创建  function fun(){}
 *  - 使用函数表达式创建
 *          匿名函数 function(){}
 *      创建一个匿名函数,将匿名函数复制个一个变量
 * 
 * 立即执行函数---只调用一次
 *  - 函数定义玩立即被执行,往往只会执行一次
 *  - (匿名函数)(参数)        (function(){})();
 *      ()标识它是一个整体
 * 
 * 调用函数
 *  - 函数名()
 *  - 调用函数时,解析器不会检查实参的数量
 *      实参数量少于形参数量,则没有对应实参的形参将是 undefined
 * 
 * 函数的返回值
 *  - return 值;
 *  - return 之后的语句不会执行
 *  - return 之后不跟任何值相当于返回一个 undefined
 *  - 不写return 也会返回undefined
 *  - 可以是任何类型,对象、函数对象、函数的返回值也可以
 * 
 * 作用域
 *  - 指一个变量的作业范围
 *  1. 全局作用域/变量
 *      - 页面打开时创建,页面关闭时销毁
 *      - 在全局作用域中有一个全局对象 window
 *          它代表浏览器的窗口,浏览器创建,可直接使用
 *      - 全局变量会作为 window对象的属性保存
 *  2. 函数作用域/变量
 *      -调用函数时创建函数作用域,函数执行完毕后,函数作用域销毁
 *      - 每调用一次函数就会创建一个新的函数作用域,他们相互独立
 *      - 在函数作用域中可以访问到全局作用域的变量
 *          在全局作用域中不可以访问函数作用域的变量
 *      - 当在函数作用域中操作一个变量时,先在自身作用域中寻找,如果有则直接使用,没有去父级找
 *      - 在函数作用域中想访问全局作用域可以使用window
 * 
 * 
作用域:js代码所作用的范围。
1. 一旦进入作用域,浏览器就会启动JS解析器。
2. 声明在script作用域中的变量,称为全局变量。作用范围:整个页面。生存周期,与页面同寿。同时也是顶级对象window的属性。
声明在函数作用域中的变量,称为局部变量,作用范围:仅限于当前函数内。生存周期:函数调用时开辟空间,函数调用结束后,释放空间。
3. 使用变量时,首先在自己作用域中查找,如果没有,向父级作用域查找,依次向上查找,一直查找到script作用域,这个过程称为作用域链。
一、预解析(var function 形参)
    //1. 当找到var时,取出var后面的名字放到内存中,并且给它初始化一个undefined值.
    //2. 当找到function时,取出function后面的名字放到内存中,并且将整个函数块赋值给这个名字。
    //3. 当变量与函数同名时,丢变量,保函数。
    //4. 多个script作用域时,从上到下依次解析每一个script,所以上面script作用域中找到的东西,下面可用。如果是下面找到东西,上面无法使用。建议将所有声明的语句放到第一个script作用域中。
    //5. 隐式声明的变量会因为赋值号的关系,在全局作用域中自动生成这个变量。
二、逐行解读代码(遇到函数声明,直接跳过)
    1. 执行表达式
    2. 函数调用(函数也是一个作用域)
        一、预解析(var function 形参)
        二、逐行解读代码
            1. 执行表达式
            2. 函数调用
 */
/**
 * 变量的声明提前
 *  - 使用var关键字声明的变量,会在所有代码执行之前被声明(但赋值不会),所以可以提前使用变量
 *    但是如果声明变量时不用var,则变量不会被提前声明
 * 
 * 函数的声明提前
 *  - 使用函数声明形式创建的函数,会在所有代码执行之前被声明,所以可以提前使用函数
 *     但是使用函数表达式创建的函数,不会被提前声明
 */
//var fun = new Function("console.log('12')");
//var fun =function("匿名");
(function(a,b){
    console.log(a);
    console.log(b);
})(12,13);
/**
 * 解析器在调用函数每次都会向函数内部传递一个隐含的参数 this
 *  this指向的是对象,这个对象我们称为 函数执行的上下文对象
 *  根据函数的 调用方式 的不同,this 指向不同的对象
 *      1. 以函数的形式调用时,this指向的永远是 window
 *      2. 以方法的形式调用时,this指向的是调用方法的对象 
 */
function fun(){
    console.log(this.name)//如果改为name,下面输出全是"window's"
}
var name = "window's";
var obj = {
    name : "object's",
    sayName : fun
};
var obj2 = {
    name : "object2's",
    sayName : fun
};
fun();//"window's"
obj.sayName();//"object's"
obj2.sayName();//"object2's"

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值