JS经典小栗子
- 函数提升在变量提升之前,当函数跟变量名重复的时候,如果变量没有被赋值,则函数生效。🌰:
console.log(a);
a();
var a=3;
function a() {
console.log(10)
}
alert(a)
a()
等同于:
function a() {
console.log(10)
}
var a;
console.log(a); // 打印函数体
a(); // 10
a=3;
alert(a) // 3
a() //报错 a is not a function
扩展🌰:
var a = function xxx(n) {
xxx = n; // 上面呢一行是表达式,xxx是只读的。不能被修改
console.log(typeof xxx); //function
return 1;
}
a(1)
console.log(typeof xxx); // xxx只能在内部上面函数内部访问?外部访问不了??
- this谁调用指谁
this.a = 20
var test = {
a: 40;
init: function() {
console.log(this.a)
}
}
test.init(); // test调用的,this指向test,打印:40
var dn = test.init;
dn(); // 相当于是window调用的,答应20
扩展🌰:
this.a = 20
var test = {
a: 40;
init: function() {
function go() {
console.log(this.a)
}
go() // 没有明确对象去调用go,所以这里是指向window, 打印20
}
}
test.init() // 20, 解释同上
扩展🌰🌰:
function test(a) {
this.a = a
}
test.prototype.a = 20;
test.prototype.init = function() {
console.log(this.a);
}
var s = new test(30);
a.init(); // 30 构造函数的值要优先于原型链,构造函数中找不到会到原型链上找
扩展🌰🌰🌰:
this.a = 20
var test = {
a: 40;
init: function() {
console.log(this.a)
}
} ; // **此处必须有分号‘;’,如果没有分号,会把后面()里的内容当成参数传给{}部分**
(function() {
var fn = test.init
fn(); // 20
})()
扩展🌰🌰🌰🌰:
this.a = 20
var test = {
a: 40;
init: () => {
// 等同于 外部调用时test.init.bind(this)
console.log(this.a)
}
}
test.init(); // 20 箭头函数会绑定作用域 ???
扩展🌰🌰🌰🌰🌰:
var test = 11;
var s= {
a:function() {
console.log(this.test+1)
},
b() {
console.log(this.test)
}
}
var f = s.a.bind(this);
new f(); // 12
var p = s.b.bind(this);
new p(); // 报错,p is not a constructor,原因: es6新的函数方式(b(){})不支持new
p(); // 这样可以执行
扩展🌰🌰🌰🌰🌰🌰:
var test = 11;
var s= {
a:function() {
console.log(this)
}
}
var f = s.a.bind(this);
new f(); // a(){}; new优先级高于bind,new之后bind失效,this指向new的实例。
3.
function xxx() {
console.log(1);
}
(function () {
var a = 1;
if (false) {
function xxx() {
console.log(2);
}
}
xxx();
})();
上例运行结果不同浏览器不同,老版IE会把函数体提升,打印2;新版浏览器如FireFox认为if(false)不应该提升,应该只是变量提升,所以将var xxx 提升到函数体顶部,xxx()运行报xxx is not a function;
- 将字符串转换成数组, 基于var x = ‘asdf’, 目前想到以下方法:
- x.split()
- Array.from(x)
- […new Set(x)]
- Array.prototype.slice.call(x)
总结
- 函数提升 变量提升, 函数提升优先于变量提升;
- 当函数名和变量名相同时,如果变量没有被赋值,则函数生效,否则变量生效;
- var s = function g(){}; g是只读的,g只能在函数内部访问
- this谁调用指向谁,没人调用他就指向window;
- this 当函数创建的时候,this指向当前函数的实例;
- 简单的函数声明(a(){}; a:()=>{})不能被new
var s = {
a:function(){
console.log(1);
},
b(){
console.log(2)
}
};
var f = s.a.bind(this);
new f();
var p = s.b.bind(this);
new p();
- es6简写的函数体a(){}不能被new this!!!
- 对象和闭包不能在一起,必须有分号;
- function test(a){
this.a = a;
}
test.prototype.a = 20;
test.prototype.init = function(){
console.warn(this.a)
}
var s = new test();
s.init() - TDZ 暂时性死区