您的位置:首页 > Web前端 > JavaScript

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

2017-08-28 09:14 239 查看

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,和在哪里执行的无关
}()
}




函数的预解释:

自执行函数不进行预解释

js内存的释放



堆内存释放

堆内存的释放

对象或者

函数 定义时候都会开辟堆内存

规则

对象数据类型或者函数数据类型在定义的时候,首先会开辟一个队内存,堆内存有一个引用地址,如果外边有变量等知道了这个地址,我们就说这个内存被占用了,就不能被销毁了.

我们想让堆内存释放/销毁,只需要把所有引用它的变量值赋值给null即可.如果当亲啊堆内存没有被任何东西占用,则浏览器在空闲的时候把他销毁i

var obj = {name:"maotai"};
var obj2 = obj;




obj = null;
obj2 = null;


栈内存的释放

全局作用域:只有当页面的关闭销毁

私有作用域: 只有函数执行时候会产生私有的作用域.

以下是代码块,不会开辟私有作用域.

for(){}
if(){}
switch(){}


一般情况下,函数执行会形成一个新的私有作用域,当私有作用域中的代码执行完成后,我们当前的作用域都会主动的进行释放和销毁.

特殊情况:

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



特殊情况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类型数据



特殊情况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)



另外一道题

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




案例多种方法

实现效果: 点button数字累加



案例:实例

实现点击自加:



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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: