在某网课学习前端笔记整理js篇17-js中this指针、var、作用域、解析与执行过程

js中this指针、var、作用域、解析与执行过程

this指针

内容来自 https://www.cnblogs.com/pssp/p/5216085.html,这里摘录了这位前辈的部分内容。

​ this在面向对象中一般指向的是对象本身,在js中函数中也有this。this在指向函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是哪个调用它的对象。

example1

function a(){
    var user = "追梦子";
    console.log(this.user); //undefined
    console.log(this); //Window
}
a()//window.a(); //默认函数的this指向就是window对象。

注:在严格版中的默认的this不再是window,而是undefined。

example2

var o = {
    user:"追梦子",
    fn:function(){
        console.log(this.user);  //追梦子
    }
}
o.fn();

​ 这里的this指向的是对象o,因为你调用的fn是通过o.fn()执行的。

example3

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //12
        }
    }
}
o.b.fn();

​ 这里的可能会有指向a还是b的疑惑,”this的最终指向的是哪个调用它的对象“指的是直接调用他的对象,多个对象调用时this指向的是上一级对象。

example4

var o = {
    a:10,
    b:{
        a:12,
        fn:function(){
            console.log(this.a); //undefined
            console.log(this); //window
        }
    }
}
var j = o.b.fn;
j();

​ 看了example3,可能会想:卧槽,不是指向上一级对象么?其实这里的o.b.fn并没有执行,只是单纯的把fn这个函数复制给了j这个引用,实际上调用j()的是window这个对象,即最后一个代码是window.j().

example5

//构造函数版this
function Fn(){
    this.user = "追梦子";
}
var a = new Fn();
console.log(a.user); //追梦子

​ 这里的var a = new Fn()是创建有一个对象(相当于复制了一份Fn到对象a里面),那么这里的this当然是指向了a。

example6

function fn()  
{  
    this.user = '追梦子';  
    return {};  
}
var a = new fn;  
console.log(a.user); //undefined

function fn2()  
{  
    this.user = '追梦子';  
    return function(){};
}
var b = new fn2;  
console.log(b.user); //undefined

function fn3()  
{  
    this.user = '追梦子';  
    return 1;
}
var c = new fn3;  
console.log(c.user); //追梦子

​ 如果函数返回值是一个对象,那么this指向的就是那个返回的对象,如果返回值不是一个对象,那么this还是指向函数的实例。构造函数默认返回的就是this 实例化的对象使用this就可以找到自己的属性和方法 通常构造函数return是可以省略的

example7

//修改函数this指针的三个方法
window.a = 1;
window.b = 2;
document.a = 10;
document.b = 20;
function fn(param){
	console.log(this.a,this.b,param);
}
fn("默认");//1 2 "默认"
fn.call(document,"call");//10 20 "call"
fn.apply(document,"apply");//10 20 "apply"
fn.bind(document,"bind");//10 20 "bind"

​ call和bind的参数是一个个传入的,而apply是一次性传入一个数组,bind返回的是一个引用,需要加上()来指向函数。这三个方法都可以来改变函数的默认指针this。

var与变量提升

var用来声明变量。还有个和lvar作用差不多的let,不过let是严格模式中的,可以想成正常其他语言声明变量,不像var表现的不符合正常人的逻辑。

下面部分内容参考:https://www.cnblogs.com/52fhy/p/5117267.html

​ 一般情况下,是可以省略var的,但有两点值得注意:

​ 1、var a=1a=1 ,这两条语句一般情况下作用是一样的。但是前者不能用delete删除。不过,绝大多数情况下,这种差异是可以忽略的。
​ 2、在函数内部,如果没有用var 进行申明,则创建的变量是全局变量,而不是局部变量了。

​ JavaScript引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这造成的结果,就是所有的变量的声明语句,都会被提升到代码的头部,这就叫做变量提升(hoisting)。

注:全局变量我感觉就是window对象下的一个变量。

example8

var a = 1;
b = 2;
delete a;
delete b;
console.log(a);//1
console.log(b);//报错

var c = 3;
var f = function fn(){
	c = 4;
	d = 5;
}
console.log(c);//4
console.log(d);//5
console.log(f.d);//undefined

作用域

​ js中只有全局作用域和函数作用域。控制语句(for,while,if…)并不会生成作用域。

example9

for(var i = 0;i < 4;i++);
console.log(i);//4

解析与执行过程

部分内容参考自https://www.cnblogs.com/foodoir/p/5977950.html

JavaScript引擎的工作方式是,先解析代码,获取所有被var声明的变量声明方式声明的函数,然后再一行一行地运行。这可以解释很多js中让人费解的代码。

example10

alert(num);
var num = 10;
alert(num);

解析:
	num:undefined
执行:
	结果为:
		undefined 
		10

example11

f1();
f2();
a = 3;
function f1(){//声明的方式声明的函数
	console.log("f1");
}
var f2 = function(){//函数表达式
	console.lgo("f2");
}

解析:
	f1:函数的引用
	f2:undefined
	没有a
执行:
	执行结果:
		f1
		报错:f2 is not defined

​ 解析的时候出现相同的名字会怎么样呢?

example12

var a = 1;
var a = 2;
console.log(a);//2

example13

console.log(a);//ƒ a(){}
var a = 1;
function a(){
}
console.log(a);//1 这里容易误解,想想解析执行过程,其实这里的a最后执行了a=1,所以结果不是函数。

example14

console.log(fn);//f fn(){console.log("second")}
function fn(){
	console.log("first");
}
function fn(){
	console.log("second");
}

example12example13example14现象的原因:处理函数声明有冲突时,会覆盖;处理变量声明有冲突时,会忽略;函数声明和变量声明冲突,函数声明会覆盖变量声明。

example15

function f(a,b){
    alert(a);
    alert(b);
    
    var b = 100;
    function a(){}
}
f(1,2);

解析:
	f:函数的引用
执行:
	执行f(1,2)
	解析:
		b:undefined
		a:指向函数引用
		arguments:2
	执行:
		弹出:f a(){}
		弹出:undefined

函数中的解析和执行过程的区别不是很大,在执行到函数的时候需要再解析下函数内容。 但是函数中有个arguments我们需要注意一下。

发布了27 篇原创文章 · 获赞 0 · 访问量 220

猜你喜欢

转载自blog.csdn.net/qq_34338676/article/details/104715539