-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy pathjavascript-函数.js
More file actions
307 lines (250 loc) · 6.99 KB
/
Copy pathjavascript-函数.js
File metadata and controls
307 lines (250 loc) · 6.99 KB
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
----------------------------
基本概念 |
----------------------------
# 函数的类型
Function
# 关于函数重载
* 首先要明确一个概念,重载的概念
* 方法名相同,但是方法名不同.
* JavaScript中没有函数重载这个概念,也不支持
* JavaScript的原则是,就近原则.谁近调谁
调用语句前面定义了两个同名函数,一个是 基本定义方式,一个是匿名定义方式,则匿名定义方式优先
* 但是我们可以通过一些操作,来模拟函数重载
1,在函数内部有一个:arguments数组,它封装了来自调用者传递的参数
2,我们可以获取到这个数组,然后,通过传递的参数进行判断.来模拟重载的操作
function demo(a,b,c)
{
for(var x = 0;x < arguments.length ;x ++)
{
document.write(arguments[x]);
}
}
# 解析顺序
1,优先找匿名函数
2,其次找function函数
* 多个同名function,最后一个会覆盖以上的所有
# 属性
length
* 返回函数的形参数量
# 可以给函数自定义属性/访问
function test(){}
test.name = "test"; //设置
test.name; //访问
----------------------------
定义方式 |
----------------------------
# 基本定义方式
function test(){}
* 这种方式定义的函数,可以在任何可见的地方调用
# 匿名函数,ECMA推荐方式
var test = function(){}
* 该函数以变量的形式存在
* 如果调用代码在前,而函数定义代码在后,则会调用失败
* 该函数一般用于参数传递/事件监听
arr.forEach(function(val){
});
window.onLoad = function(){
}
# 另类的定义
var method = new Function("参数列表","方法体");
* 用的少,理解就好.需要使用到js里面的内置对象: Function
* var method = new Function("参数列表","方法体");//也被称之为动态函数
var method = new Function("x,y","return x+y");
alert(method(1,2)); //弹窗值为3
* 这个东西的强大之处在于这个体现形式
* var canshu = "x,y";
* var body = "return x+y";
* var method = new Function(canshu,body);
* 如果调用代码在前,而函数定义代码在后,则会调用失败
# 区别
function 语句 函数直接量(匿名) Funtion 构造函数
--------------------------------------------------------------------
兼容 完全 js1.2以上 js1.1以上
--------------------------------------------------------------------
形式 句子 表达式 表达式
--------------------------------------------------------------------
名称 有名 匿名 匿名
--------------------------------------------------------------------
性质 静态 静态 动态
--------------------------------------------------------------------
解析时机 优先解析 顺序解析 顺序解析
--------------------------------------------------------------------
作用域 具有函数作用域 具有函数作用域 顶级函数(顶级作用域)
--------------------------------------------------------------------
# 静态与动态
静态
* 当解析到函数定义代码后,就会立即创建函数对象,存在内存中,供调用
* 占内存,效率高,适合多次调用
动态
* 每次调用的时候,才会去创建该函数
* 不占内存,效率低,适合单次调用
# 作用域
function 语句和 函数直接量的作用域都是一样,只有 Function构造函数的作用域是全局的
----------------------------
参数与 arguments 对象 |
----------------------------
# 函数体内都有一个 隐形 的变量:arguments
# 该变量本质是一个数组,里面存储了函数调用传入的参数
# JS函数的参数是非常灵活的,形参个数可以跟实参个数不一样
# 获取函数形参的长度
* 函数名.length
function test(a,b,c){}
console.log(test.length); //3
# 获取函数实参的长度
* 函数内部使用 arguments的length属性,来获取
function test(){
console.log(arguments.length);
}
# arguments 与 递归
arguments.callee;
* 该属性,会返回当前函数本身的引用
* 可以获取到当前函数,来执行递归操作
* 递归
function test(a){
if(a === 100) return a;
return arguments.callee(++a);
}
console.log(test(1)); //100
# 获取当前函数的名称
arguments.caler;
----------------------------
this 对象 |
----------------------------
# this 对象是在运行的时候基于函数的执行环境绑定的
# 在全局函数中,this 指向 window 对象
# 对象函数中的 this,则指向对象本身
* 谁调用,this 指向谁
----------------------------
call,apply/bind高级函数 |
----------------------------
# 每个函数,都包含两个非继承而来的方法
* 只要你是个函数,就有这俩方法
call(obj,p1,p2...);
apply(obj,[p1,p2]);
* call 后面是1-n个参数
* apply 后面是一个数组
# call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的
# '换句话说,就是为了改变函数体内部 this 的指向,第一个参数传递啥,this就指向啥'。
# 这俩函数作用
* 传递参数
* 扩充函数依赖以运行的作用域
# 执行环境的切换Demo
//全局变量
window.color = 'red';
var obj = {
//对象变量
color :'blue'
}
function showColor(){
//打印 this 的color
console.log(this.color);
}
showColor(); //red ,this 指向当前 window
showColor.call(obj); //blue,通过 call,把showColor函数的执行环境指向了 obj 对象,此时,showColor的 this 就是obj
# bind
* 跟apply和call差不多,不过它是返回新的函数
* bind 方法返回的函数并不包含: prototype 属性
var y = 5;
var o = {y:15};
function f (x){
return x + this.y;
}
f(5); //10
//绑定到指定的对象上,返回新的函数
var bf = f.bind(o);
bf(5); //20
----------------------------
执行环境的概念 |
----------------------------
# 执行环境定义了变量或函数是否有权访问其他数据,决定了他们各自的行为
# 每一个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中
* 这个变量,无法通过JS代码来获取
# 图解执行环境
-------------------
|var x = 10; |
|var y = 20; | 保存在变量
|function a (){ | ==================> var obj;
| //TODO |
|} |
-------------------
# Demo
var color1 = 'blue';
function changeColor(){
// changeColor 可以访问 c1,c2
var color2 = 'red';
function swapColor(){
//swapColor 可以访问 c1,c2,c3
var color3 = color2;
color2 = color1;
color1 = color3;
}
swapColor();
}
changeColor();
//只能访问c1
println(color1);
----------------------------
垃圾回收机制 |
----------------------------
# JS具备垃圾回收机制,开发不用关心内存分配与回收
# 垃圾回收
离开作用域的值,将会被标记-可回收,在垃圾收集期间被删除。标记清除是目前主流的垃圾收集算法
----------------------------
块儿级作用域 |
----------------------------
# JS 没有块作用域的概念
# 演示
function test(){
for(var x = 0; x < 10; x++){
}
console.log(x); //输出10,是可以访问到x的
}
test();
if(((x = 5) == 4)){
console.log(x);
}
console.log(x); //输出 5
# 解决
* 使用匿名执行作用域,该作用域中的变量,执行完毕后会被立即回收
function test(){
(function(){
for(var x = 0;x < 10 ;x ++){
console.log(x);
}
})();
console.log(x); // x is not defined
}
test();
# 语法格式
(function(){
//执行体
})();
----------------------------
闭包 |
----------------------------
# 闭包
var x = "1";
var obj = {
x : '0',
test : function(){
return function(){
return this.x;
}
}
}
var fun = obj.test();
console.log(fun()); //1
var x = "1";
var obj = {
x : '0', //定义变量O,保存当前对象
test : function(){
var o = this;
return function(){
return o.x; //返回当前对象的x
}
}
}
var fun = obj.test();
console.log(fun()); //0
# 说白了,一个函数的返回值,是一个另一个函数.另一个函数可以访问该函数的变量
# 可以用来保护变量