[js]02js预解释-作用域-this关键字

js预解释 作用域 this关键字

  • 预解释
  • 作用域
  • this

如何查找当前作用域的上一级作用域?

  • 看当前函数是在哪个作用域下定义的,那么它的上级作用于就是谁
  • 和函数在哪执行的没任何关系
var  num = 12;
function fn() {
    var num = 120;
    return function () {
        console.log(num);
    }
    var f = fn();
    f(); // 上一级作用于是A
    ~function () {
        var num = 1200;
        f(); // 上一级作用于是A,和在哪里执行的无关
    }()
}

image

函数的预解释:

自执行函数不进行预解释

js内存的释放

image

堆内存释放

  • 堆内存的释放

    • 对象或者
    • 函数 定义时候都会开辟堆内存
  • 规则

    • 对象数据类型或者函数数据类型在定义的时候,首先会开辟一个队内存,堆内存有一个引用地址,如果外边有变量等知道了这个地址,我们就说这个内存被占用了,就不能被销毁了.
    • 我们想让堆内存释放/销毁,只需要把所有引用它的变量值赋值给null即可.如果当亲啊堆内存没有被任何东西占用,则浏览器在空闲的时候把他销毁i
var obj = {name:"maotai"};
var obj2 = obj;

image

obj = null;
obj2 = null;

栈内存的释放

  • 全局作用域:只有当页面的关闭销毁
  • 私有作用域: 只有函数执行时候会产生私有的作用域.
    • 以下是代码块,不会开辟私有作用域.
for(){}
if(){}
switch(){}
  • 一般情况下,函数执行会形成一个新的私有作用域,当私有作用域中的代码执行完成后,我们当前的作用域都会主动的进行释放和销毁.

  • 特殊情况:

    • 当前私有作用域中的部分内存被作用域意外的东西占用了,那么当前这个作用域就不能被销毁了.
      image

    • 特殊情况1:
      函数执行返回了一个引用数据类型的值,并且在函数在外边被一个其他的东西接受,这总请客下一般形成的私有作用域不会被销毁.


function fn() {
    var num = 1000;
    return function () {

    }
}
var f = fn() //fn执行形成的私有作用域就不能被销毁了
  • 特殊情况2
    在一个私有作用域中给DOM元素的事件绑定方法,一般情况下,我们的私有作用域都不能销毁
var oDiv = document.getElementById("div1");
~function () {
    Odiv.onclick = function () {

    }
}(); //当前私有作用域不能被销毁

ps: 通过getelement取得的是object类型数据

image

  • 特殊情况3:

不立即销毁–>fn返回函数没有被其他东西调用,但是还需要执行一次呢,所以暂时不小hi,当返回值执行完成后,浏览器会在空闲时候把他销毁.


function fn() {
    var num = 100;
    return function () {

    }
}
fn()();

作用域实战题

function fn () {
    var i = 10;
    return function(n){
        console.log(n+(++i));
    }
}

var f = fn();
f(10); //21
f(20);//32

fn()(10);//21
fn()(20);//31

![image]http://ww1.sinaimg.cn/large/9e792b8fgy1fiez0429g1j213e0gjajx)

image

另外一道题

function fn (i) {
    return function(n){
        console.log(n+(i++));
    }
}

var f = fn(13);
f(12); //25
f(14);//28

fn(15)(12);//27
fn(16)(13);//29

使用闭包作用域的方式实现选项卡循环绑定事件的处理

this关键字

console.log(this) //window
  • js中this代表的是当前行为执行主体, 我们主要研究函数中的this
function 吃饭(){
    this-->张三
}
张三.吃饭()
  • js中context代表当前行为执行的环境或区域.

    • 张三在沙县小吃 吃蛋炒饼, this是张三, context是沙县小吃.
  • this是谁和函数在哪定义的 和 在哪里执行的都没任何关系.

~function(){
    张三.吃饭();
}

如何区分this?

  • 1,函数执行,首先看函数名前面是否有 “.”,有的话”.”是谁,this就是谁, 没有的话,this就是window
function fn() {
    console.log(this);
}
var obj = {fn:fn};
fn();// this-->window
obj.fn();// this-->obj
function sum(){
    fn(); // this-->window
}

sum();
function fn() {
    console.log(this)
}
var oo = {
   // sum里的this是oo
    sum: function () {
        fn(); // this--> window
    }
}
oo.sum();
  • 2,自执行函数中的window,永远是window
  • 3,给元素的某一个元素绑定方法,当事件触发的时候,执行对应的方法,方法中的this是当前的元素.
<div id="div1" style="width: 100px;height: 100px;background-color:green;">123213123</div>

<script>
function fn() {
    console.log(this) // this ->document.getElementById("div1")
}
document.getElementById("div1").onclick=fn;
</script>

结果:

<div id="div1" style="width: 100px;height: 100px;background-color:green;">123213123</div>

另一个例子:

document.getElementById("div1").onclick=function(){
    // this--> #div1
    fn(); // this->window
};

实战题



var num = 20;
var obj = {
    num: 30,
    fn:(function (num) {
        this.num*=3;
        num +=15;
        var num = 15;
        return function () {
            this.num*=4;
            num+=20;
            console.log(num);
        }
    })(num)
};
var fn=obj.fn;
fn(); //35
obj.fn(); //55
console.log(window.num,obj.num) //240 120

image

案例多种方法

实现效果: 点button数字累加

image

案例:实例
实现点击自加:

1.利用全局作用域不销毁原理.把需要累加的数字定义为全局变量

    var oBtn = document.getElementById("btn");
    var spanNum=document.getElementById("spanNum");
    var count=0;
    btn.onclick=function () {
        count++;
        spanNum.innerHTML=count;
    }
//弊端:为了防止项目中全局变量之间的冲突,我们一般是禁止使用全局变量.

2.思想:自建一个不销毁的私有作用域

~function(){}();

~function(){  // 在私有作用域中给外部的一个元素对象的某一个事件绑定一个方法.
    var oBtn = document.getElementById("btn");
    var spanNum=document.getElementById("spanNum");
    var count=0;
    btn.onclick=function () {
        count++;
        spanNum.innerHTML=count;
    }    
}();

3,思想和2相同

返回一个引用类型给oBtn,则自执行函数也无法被销毁.

oBtn.onclick=(function(){
    var count = 0;
    return function(){
        count++;
        spanNum.innerHTML=count;
    }
})();
//弊端: 占用内存

4.第三种方法:利用innerHTML的方式处理:每一次点击的时候,都先回到页面中获取值,然后累加,最后把累加的结果放回去.

oBtn.onclick=function(){
    //spanNum.innerHTML=spanNum.innerHTML+1; //获取的是字符串,有问题
    spanNum.innerHTML++;//自动转换,且实现自加.
};
//弊端: 每一次都要把页面中的内存先转换为字符串,然后累加,累加完成后重新添加回去,当重新欠佳的时候浏览器都需要重新渲染

5.利用自定义属性存储.

oBtn.count=0; //给oBtn添加属性
oBtn.onclick=function(){
    spanNum.innerHTML=++this.count;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值