在函数内部,一般用var声明的为局部变量,只要一定义会提升到函数的开头处,es6之前没有块级作用域,没用var声明的一般为全局变量。
没有用var声明的变量都是全局变量,而且是顶层对象的属性,window.对象属性,在window中可以访问得到
在这里插入代码片
var a = 100;
function test(){
console.log(a);
a = 10;
console.log(a);
}
test();
console.log(a);
解释:在test函数内,a=10声明了一个全局变量,所以第3行的a应该输出全局变量的值,而在函数执行之前已经声明过一个全局变量并赋值100,所以这里第上输出100。第4行给全局变量a 重新赋值10,所以全局变量a的值变成10,所以第5行输出10。而在函数test外部,第8行输出全局变量a的值,因为a=10。所以输出10
this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象调用时,this等于那个对象。不过,匿名函数具有全局性,因此this对象同常指向window
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){ //匿名函数
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());//result:The Window
var声明的变量会提升。但是定义不会提升。
函数声明可以被提前,但是函数表达式不会被提前
例如
var x = foo();
var foo = function foo(){
}
实质是
var x;
var foo;
x = foo() // 赋值会报错 ,foo为undefined , 不是函数类型
foo = funcition foo (){}
解答:aa函数有个叫bb的参数。所以aa的作用域有bb的这个属性。因此bb = 2是给aa里的bb的赋值。成为自身函数的作用域变量。不会影响到外部的window bb
1 var a = 10;
2 function test(){
3 a = 100;
4 console.log(a);
5 console.log(this.a);
6 var a;
7 console.log(a);
8 }
9 test();
在函数test执行前,由于第6行声明了局部变量a,所以函数内部的a都指向已经声明的局部变量。所以第4行输出100。
第5行输出this.a,我们都知道,函数内部的this指针指向的是函数的调用者,在这里函数test被全局对象调用。所以this指针指向全局对象(这里即window) ,一开始全局变量a=10,所以第5行输出结果为10
第7行输出结果为100,因为局部变量a在第3行已经被赋值了100,所以直接输出局部变量a的值。
var m1 = main(); 全局环境下定义的变量会被当做全局对象的属性,这个属于window
var m2 = new main(); 这个指向m2。在局部环境下,局部变量不会被当做对象的属性,如:var foo = 3就不是main的属性
考察new的原理
var foo = 1;
function main(){
alert(foo);
var foo = 2;
alert(this.foo)
this.foo = 3;
}
//1.请给出以下两种方式调用函数时,alert的结果,并说明原因。
var m1 = main();
var m2 = new main();
var m1=main()时,alert的结果是undefined和1。var foo = 2,var变量提升到函数内部最前。因此提示undefined。
而this.foo时,因为此时的函数执行环境是全局域,相当于window.main(),因此this=window,所以this.foo=window.foo=1。
var m2=new main()时,alert的结果是undefined和undefined,第一个undefined的原因与前面一种情况相同。第二个提示undefined的原因是在这种情况下用new构造,因此执行环境发生了改变,不再是全局域,而是m2。this.foo=m2.foo,但是由于在alert(this.foo)时,m2中的this.foo还未被定义。因此提示undefined。
同理,这道题。
9999 4400
//new 的原理
Function.prototype.a = 'a'
Object.prototype.b = 'b'
function Person(){}
var p = new Person()
console.log(p.a)
console.log(p.b)
解释:new 构造函数的过程。最终返回的是一个对象
1、创建一个空对象
2、将空对象的原型设置为构造函数的原型
3、改变空对象的this指向,使之指向构造函数
4、返回这个对象
所以 new Person() 返回的p是对象,属于OBject的实例,没有继承functiion。p先在自己的作用域内找属性,没找到再去对象的OBject里找 属性。
只是person函数本身继承了Funciton,所以通过person.a是可以访问function里面的原型的
先在当前作用域中查找,如果找到就直接使用,如果没有找到,那么就到上一级作用域中查找
一般情况下,变量取值是到创建这个变量的函数作用域中取。但是如果在当前作用域没有查到该值,就会向上级作用域去查,直到查到全部作用域,这样一个查找的过程就形成了作用域链。
var a1 = "a1";
var b1 = "b1";
function func(){
var a1 = "n1";
console.log(a1); //n1(此行a1先在func函数内部作用域中查询;
console.log(b1); //b1 b1在函数作用域没找到,则在全局window中查找
}
func();
name="lwy";
function t(){
var name="tlwy";
function s(){
var name="slwy";
console.log(name);
}
function ss(){
console.log(name);
}
s();
ss();
}
t();
name是"slwy"。
但执行ss()时,作用域链是: ss()->t()->window,所以name是”tlwy"
js的执行过程:
预解析阶段 变量var声明会提升和函数的提升(声明);
具体的执行阶段
console.log(a); //undefined 变量申明提升,var a
var a = 10;
f1(); //f1 , 函数提提升 function f11()
function f1(){
console.log("f1");
}
f1(); // 报错。 const f 是一个const声明 , f不会提升
const f = function f1(){
console.log("f1");
}
变量和变量同名的情况:后面的变量会把前面的变量覆盖;
函数和函数同名的情况,后面的函数会覆盖前面的函数.
var n1 = "n1";
console.log(n1); //n1
function test(){
console.log(n1);
}
test(); //n1
var n1 = "new n1"; //覆盖了之前n1的值
console.log(n1); //new n1
test(); //new n1
f1(); // 20
function f1(){
console.log(10);
}
f1(); //20
function f1(){
console.log(20);
}
f1();//20
f1()
f2()在函数调用的时候会创建两个执行环境,保存各自的变量对象,结果没有关系。而同一个函数在多次调用时返回值会被保存在同一个变量对象中。所以,f1 0 1
f2 0
number(empty ,null,0) 都为 0
number(undefined) NAN
number([]) 为0
number({})为NAN
数字后面加.会被解析为数字小数点
2.toString() 错误
2 .tostring() 正确
(2).tostring() 正确
Boolean(null,undefined ,’’,NAN,0)都为 false 其余都为true
([])?true:false ----> true
([]==false)?true:false 相当于比较number([])==false 结果为true
({}==false)?true:false 相当于比较number({})==false 结果为false
Math.round()四舍五入,
小数>0.5,取绝对值最接近右边的整数
小数<0.5,取绝对值最接近左边的整数
Math,round(2019.22) 2019
Math,round(2019.50) 2020
Math,round(-2019.50) -2019
Math,round(-2019.61) -2019
js的内置对象