# 不知道的 JavaScript
# 例 1
if(false){
var a= 1;
}
console.log(a)//undefined
解释其过程
首先变量提升
var a
if(false){
a=1
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 拓展 1
function test(){
console.log(1)
}
var test;//忽略掉test为undefined变量
console.log(test)//function test(){console.log(1)}
1
2
3
4
5
2
3
4
5
# 拓展 2 函数表达式定义的时候函数的名字外部不能被访问,内部不能被修改
var p=function test(){
//只能在函数内部访问
test =1;
console.log(typeof test)//function
}
p()
console.log(test)//报错 ,函数表达式外部不能访问test,只能在函数内部访问
1
2
3
4
5
6
7
2
3
4
5
6
7
# 例 2 this
var o={
foo:function(){
console.log(11)
},
bar(){
console.log(22)
}
}
var p1=o.foo.bind({});
new p1();
var p2=o.bar.bind({}) ;//ES6 bind不能被new
new p2();//报错了,p2 is a not construct
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 拓展 1
this.a = 20;
function test(){
console.log(this.a)
}
var obj ={
a:40,
}
var result=test.bind(obj)
new result();//undefined new 会对bind失效
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 拓展 2 bind 的实现
if(!Function.prototype.bind ){
Function.prototype.bind = function(oThis){
if(typeof this !=='function'){
throw new TypeError('请使用函数绑定')
}
var oArg = Array.prototype.slice.call(arguments,1),
fTobind =this,
FNOP =function(){
},
ftbound = function(){
fTobind.apply(this instanceof FNOP && oThis ?this :oThis, oArg.concat.call(Array.prototype.slice.call(arguments,1)));
}
if(this.prototype){
FNOP.prototype = this.prototype
ftbound.prototype = new FNOP();
}
return ftbound;
}
}
思路
bind(a)-->原来函数.apply(a)
function test(a,b){
var aArg = Array.prototype.slice.call(arguments)
var aArg1 = Array.prototype.slice.call(arguments,1)
console.log(aArg)//[1,2,3]
console.log(aArg1)//[2,3]
}
test(1,2,3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 拓展 3 构造函数优先级比原型链高
function C1(name){
//构造函数不存在
if(name) this.name = name
}
function C2(name){
//this.name=undefined
this.name = name
}
function C2(name){
//this.name=fei
this.name = name || 'fei'
}
C1.prototype.name = 'one'
C2.prototype.name = 'two'
C3.prototype.name = 'three'
console.log((new C1().name)+(new C2().name)+(new C3().name))//one undefined fei
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 拓展 4
解释上图:第一个是:语句优先,所以它的先执行{};然后[];所以等于 0
[object Object] 小写 object 与 Object 因为是与大写区分
# 按值传递与按引用传递
# 基本数据类型(值类型)
1.Boolean false true
2.Number NaN 最大值 最小值
3.String
4.null 根本不存在
5.undefined 通俗的说是存在但没有赋值
6.Sysbol 引入一个唯一的值
# Object
1.Array
2.RegExp
3.Date
4.Math
...
值跟对象的区别是反映在计算机的存储位置不同
使用 typeof 判断数据类型
typeof NaN //number
typeof symbol // sysmbol
typeof alert //function
typeof null //object
typeof not _ defined_var //undefined
# 按值传递
var a= 1; var b= a; b=3 alert(a)//1 alert(a)//3
# 按(址)引用传递
var o ={a:1}
var b= o;
b.xx= 2
a===b //true
# 引申
function test(m){
m = {v:1}
}
var m = {a:1}
console.log(m.v)//undefined
1
2
3
4
5
6
2
3
4
5
6
# 拓展 5
有三种答案 高程中答案是2 还有1 当前浏览器是报错 不是一个函数
函数比较特殊,在js中是一等公民
function test(){
//形成块级作用域
var a = 1;
}
test()
console.log(a)//报错 Uncaught ReferenceError: a is not defined
function a(){
console.log(1)
}
(function(){
if(false){
function a(){
consoloe.log(2)
}
}
a()
})()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 拓展 6
function test(){
//该处的this.length指的是iframe的数量
console.log(this.length)
}
test()
1
2
3
4
5
2
3
4
5
# 引申
var length =10;
function test(){
console.log(this.length)//10 2
}
var obj = {
length:5,
method:function(){
test()
arguments[0]()//相当于是arguments.fn()
}
}
obj.method(test,1)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12