Loading

08探索JS中的函数秘密

  1 <!doctype html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <meta name="viewport"
  6           content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8     <title>08探索JS中的函数秘密</title>
  9 </head>
 10 <body>
 11 <!--
 12 1 普通使用方法
 13 对象的方法中 this 指向该对象,对象方法中的函数中的 this 指向 window 对象。
 14 对象方法中使用箭头函数时 this 指向父级作用域对象。
 15 2 对象方法中使用事件监听函数
 16 对象方法中事件监听使用箭头函数时 this 指向父级作用域对象。
 17 对象方法中事件监听不使用箭头函数时 this 指向的是事件监听对象。
 18 -->
 19 
 20 <!--8.10 回调函数-->
 21 <!--<button id="bt">点我</button>-->
 22 
 23 <!--8.14.2 this在监听事件中的使用1-3-->
 24 <!--<button>百度</button>-->
 25 
 26 <!--8.14.3 this在监听事件中的使用-多个监听事件-->
 27 <!--<button>百度</button>-->
 28 <!--<button>新浪</button>-->
 29 
 30 <!--8.16.4 bind和监听绑定事件一起使用-->
 31 <!--<button>点我</button>-->
 32 
 33 <script>
 34     // 函数是对象,是一种引用类型
 35 
 36     /*8.1 函数声明的多种方式*/
 37     /*8.1.1 function直接定义的函数*/
 38     // function name(a, b) {
 39     //     console.log(a + b);
 40     // }
 41     // name(5, 3); // 8
 42 
 43     /*8.1.2 匿名函数赋值的方式定义的函数*/
 44     // let result = function (a, b) {
 45     //     console.log(a + b);
 46     // };
 47     // result(5, 3); // 8
 48 
 49     /*8.2 全局函数定义*/
 50     /*8.2.1 function直接定义的函数会放到window中*/
 51     // function baidu() {
 52     //     console.log("baidu.com");
 53     // }
 54     // window.baidu(); // baidu.com
 55 
 56     /*8.2.2 匿名函数赋值的方式定义的函数不会放到window中*/
 57     // let show = function sina() {
 58     //     console.log("sina.com");
 59     // }
 60     // show(); // sina.com
 61     // window.show(); // 报错
 62 
 63     /*8.3 匿名函数与函数提升*/
 64     /*8.3.1 function直接定义的函数有变量提升的特性*/
 65     // name(5, 3); // 8
 66     // function name(a, b) {
 67     //     console.log(a + b);
 68     // }
 69 
 70     /*8.3.2 匿名函数赋值的方式定义的函数没有变量提升的特性*/
 71     // result(5, 3); //报错
 72     // let result = function (a, b) {
 73     //     console.log(a + b);
 74     // };
 75 
 76     /*8.3.3 函数是对象,是一种引用类型*/
 77     // let result = function (a, b) {
 78     //     console.log(a + b);
 79     // };
 80     // console.log(result instanceof Object); // true
 81     // let name = result;
 82     // name(3,5); // 8
 83 
 84     /*8.4 立即执行函数与块作用域解决冲突*/
 85     /*8.4.1 立即执行函数*/
 86     // 立即执行函数不需要调用,直接执行
 87     // (function(){
 88     //     console.log("hello world!");
 89     // })(); // hello world!
 90 
 91     /*8.4.2 立即执行函数的作用域*/
 92     // 立即执行函数中的函数由于作用域的原因不属于全局作用域
 93     // (function(){
 94     //     function baidu(){
 95     //         console.log("baidu.com")
 96     //     }
 97     //     function sina(){
 98     //         console.log("sina.com");
 99     //     }
100     // })();
101     // // 由于作用域的原因无法调用下面的函数
102     // baidu();
103 
104     /*8.4.3 提升立即执行函数中的函数作用域到全局*/
105     // (function(window){
106     //     function baidu(){
107     //         console.log("baidu.com")
108     //     }
109     //     function sina(){
110     //         console.log("sina.com");
111     //     }
112     //     window.lc = {baidu, sina};
113     // })(window);
114     // lc.baidu(); // baidu.com
115     // lc.sina();  // sina.com
116 
117     /*8.4.4 使用let块级作用域的特性限制函数的作用域*/
118     // {
119     //     let baidu = function () {
120     //         console.log("baidu.com")
121     //     };
122     //     let sina = function () {
123     //         console.log("sina.com");
124     //     };
125     //     window.lc = {baidu, sina};
126     // }
127     // lc.baidu(); // baidu.com
128     // lc.sina();  // sina.com
129 
130     /*8.5 形参与实参*/
131     // (a, b)是形参
132     // let sum = function(a, b) {
133     //     return a + b;
134     // };
135     // // (1, 2)是实参,实参数量和形参数量相对应
136     // console.log(sum(1, 2)); // 3
137 
138     /*补充:
139     当形参数量大于实参数量时,多出的形参为undefined。
140     当实参数量大于形参数量时,多出的实参不被使用。
141     */
142 
143     /*8.6 默认参数的使用*/
144     // let avg = function (total, year = 12) {
145     //     return Math.round(total / year);
146     // }
147     // console.log(avg(1000,2)); // 500
148     // console.log(avg(1000));   // 83
149 
150     /*8.7 函数参数与arguments*/
151     /*8.7.1 函数参数*/
152     // let name = function (a) {
153     //     a[3] = 100;
154     //     return a;
155     // };
156     // let web = [1,2,3];
157     // console.log(name(web)); // (4)[1, 2, 3, 100]
158     // console.log(web);       // (4)[1, 2, 3, 100]
159 
160     // let exec = function (a) {
161     //     return a <= 3;
162     // }
163     // let arr = [1,2,3,4,5,6].filter(exec);
164     // console.log(arr); // (3)[1, 2, 3]
165 
166     /*8.7.2 arguments*/
167     // 基本语法
168     // let sum = function () {
169     //     // 6 Arguments(6)[1, 2, 3, 4, 5, 6, callee: ƒ, Symbol(Symbol.iterator): ƒ]
170     //     console.log(arguments.length,arguments);
171     // }
172     // sum(1,2,3,4,5,6);
173 
174     // 求和运算
175     // let sum = function () {
176     //     let total = 0;
177     //     for (let i = 0; i < arguments.length; i++) {
178     //         total += arguments[i];
179     //     }
180     //     return total;
181     // };
182     // console.log(sum(1,2,3,4,5,6)); // 21
183 
184     // let sum = function (...args) {
185     //     return args.reduce((a,b) => a + b);
186     // };
187     // console.log(sum(1,2,3,4,5,6,7)); // 28
188 
189     /*8.8 箭头函数使用语法*/
190     // 递归函数、构造函数、事件处理不方便使用箭头函数,主要考虑到作用域和this关键字的问题。
191     //  匿名赋值函数声明
192     // let name = function () {
193     //     return 1 + 2;
194     // };
195     // console.log(name()); // 3
196     // 改写为箭头函数
197     // let name = () => {
198     //     return 1 + 2;
199     // };
200     // console.log(name()); // 3
201 
202     /*8.9 使用函数完成递归算法*/
203     // let factorial = function (num) {
204     //     if (num===1){
205     //         return 1;
206     //     }
207     //     return num * factorial(num - 1);
208     //     /*
209     //     阶乘调用顺序:
210     //     return 3* factorial(3 -1);
211     //     return 2* factorial(2 -1);
212     //     return 1;
213     //
214     //     return 3* 2* 1;
215     //     return 2* 1;
216     //     return 1;
217     //     */
218     // }
219     // console.log(factorial(3)); // 6
220 
221     /*8.10 回调函数*/
222     // 在某个时刻被其他函数调用的函数称为回调函数,比如处理键盘、鼠标事件的函数。
223     // document.getElementById("bt").addEventListener("click", function() {
224     //     alert(this.innerHTML);
225     // });
226 
227     /*8.11 展开语法(点语法)正确使用方式*/
228     /*8.11.1 放*/
229     // let name = [1,2,3];
230     // let [a,b,c] = [...name];
231     // console.log(a,b,c); // 1 2 3
232 
233     /*8.11.2 收*/
234     // let [a, ...name] = [1,2,3,4];
235     // console.log(a, name); // 1 (3)[2, 3, 4]
236 
237     /*8.12 函数中this的使用*/
238     // let obj = {
239     //     site: "百度",
240     //     show: function() {
241     //         return this.site;
242     //     }
243     // };
244     // console.log(obj.show()); // 百度
245 
246     // 全局中的this
247     // console.log(window === this); // true
248 
249     //  this表示当前对象的引用
250     // let obj = {
251     //     site: "百度",
252     //     show: function() {
253     //         // 函数为对象的方法时 this 指向该对象
254     //         console.log(this);     // 对象方法中的 this 指向的为当前对象 obj。{site: '百度', show: ƒ}
255     //         function render() {
256     //             console.log(this); // 函数中的 this 指向的为 window 对象。Window{...}
257     //         }
258     //         render();
259     //     }
260     // };
261     // obj.show();
262 
263     /*8.13 通过常量改变this指针*/
264     /*8.13.1 示例1*/
265     // let lesson = {
266     //     site: "百度",
267     //     list: ["js", "css", "html"],
268     //     show: function () {
269     //         // 将当前对象 lesson 赋值给名为 self 的常量
270     //         const self = this;
271     //         return this.list.map(function (value) {
272     //             // 该函数中调用的 this 是 window 对象,通过向上找 self 调用当前对象 lesson。
273     //             return `${self.site}-${value}`;
274     //         });
275     //     },
276     // };
277     // console.log(lesson.show()); // (3)['百度-js', '百度-css', '百度-html']
278 
279     /*8.13.2 示例2*/
280     // let lesson = {
281     //     site: "百度",
282     //     list: ["js", "css", "html"],
283     //     show: function () {
284     //         return this.list.map(function (value) {
285     //             return `${this.site}-${value}`;
286     //         },this); // 将当前 lesson 对象带入到 map 函数中,有些函数有该参数,有些函数没有该参数
287     //     },
288     // };
289     // console.log(lesson.show()); // (3)['百度-js', '百度-css', '百度-html']
290 
291     /*8.14 箭头函数带来的this变化实例*/
292     /*8.14.1 普通示例*/
293     // let lesson = {
294     //     site: "百度",
295     //     list: ["js", "css", "html"],
296     //     show: function () {
297     //         return this.list.map((value) => {  // 使用箭头函数时找父级的this,即lesson对象。
298     //             return `${this.site}-${value}`;
299     //         });
300     //     },
301     // };
302     // console.log(lesson.show()); // (3)['百度-js', '百度-css', '百度-html']
303 
304     /*8.14.2 this在监听事件中的使用1*/
305     // let web = {
306     //     site: "baidu.com",
307     //     bind: function() {
308     //         const button = document.querySelector("button");
309     //         console.log(button);   // <button>百度</button>
310     //         button.addEventListener("click", function() { // button.onclick=function(){}; 既对象的方法,所以this表示当前button对象
311     //             console.log(this); // <button>百度</button>
312     //         });
313     //     },
314     // };
315     // web.bind();
316 
317     /*8.14.2 this在监听事件中的使用2*/
318     // let web = {
319     //     site: "baidu.com",
320     //     bind: function() {
321     //         const button = document.querySelector("button");
322     //         console.log(button);   // <button>百度</button>
323     //         button.addEventListener("click", () => {  // 使用箭头函数时找父级的this,即web对象。
324     //             console.log(this); // {site: 'baidu.com', bind: ƒ}
325     //         });
326     //     },
327     // };
328     // web.bind();
329 
330     /*8.14.2 this在监听事件中的使用3*/
331     // 综合this在监听事件中的使用1-2
332     // let web = {
333     //     site: "baidu.com",
334     //     bind: function() {
335     //         const button = document.querySelector("button");
336     //         console.log(button);   // <button>百度</button>
337     //         button.addEventListener("click", (event) => { // event参数对应实验1,箭头函数对应实验2。
338     //             console.log(this); // {site: 'baidu.com', bind: ƒ}
339     //             console.log(event.target); // <button>百度</button>
340     //             console.log(this.site + event.target.innerHTML); // baidu.com百度
341     //         });
342     //     },
343     // };
344     // web.bind();
345 
346     /*8.14.3 this在监听事件中的使用-多个监听事件*/
347     // 示例1
348     // let web = {
349     //     site: "站点",
350     //     bind: function() {
351     //         const buttons = document.querySelectorAll("button");
352     //         buttons.forEach((elem) => {
353     //             elem.addEventListener("click", (event) => {
354     //                 console.log(this.site + event.target.innerHTML); // 站点百度  站点新浪
355     //             });
356     //         });
357     //     },
358     // };
359     // web.bind();
360 
361     // 示例2
362     // let web = {
363     //     site: "站点",
364     //     bind: function() {
365     //         const buttons = document.querySelectorAll("button");
366     //         const self = this;
367     //         buttons.forEach(function (elem) {
368     //             elem.addEventListener("click", function () {
369     //                 console.log(self.site + this.innerHTML); // 站点百度  站点新浪
370     //             });
371     //         });
372     //     },
373     // };
374     // web.bind();
375 
376     /*8.15 构造函数*/
377     /*8.15.1 默认返回值的构造函数*/
378     // let user = function (name) {
379     //     // this 默认是空的
380     //     this.name = name;
381     // };
382     // let lisi = new user("李四");
383     // console.log(lisi); // user{name: '李四'}
384 
385     /*8.15.2 指定返回值的构造函数*/
386     // let user = function (name) {
387     //     // this 默认是空的
388     //     this.name = name;
389     //     return {age: 14};
390     // };
391     // let lisi = new user("李四");
392     // console.log(lisi); // {age: 14}
393 
394     /*8.15.3 改变this的内容*/
395     // let lisi = {
396     //     name: "李四",
397     // };
398     // let user = function (name) {
399     //     this.name = name;
400     // }
401     // let web = {url: "baidu.com"};
402     // user.call(web, "搜索引擎");
403     // console.log(web); // {url: 'baidu.com', name: '搜索引擎'}
404 
405     /*8.16 call、apply、bind的区别*/
406     /*8.16.1 call、apply、bind的基本用法*/
407     // let lisi = {
408     //     name: "李四",
409     // };
410     // let user = function (web, url) {
411     //     console.log(web + url + this.name);
412     // }
413     // // 立刻执行
414     // user.call(lisi, "百度", "baidu.com");   // 百度baidu.com李四
415     // user.apply(lisi, ["新浪", "sina.com"]); // 新浪sina.com李四
416     // // bind不立刻执行,而是生成一个新的函数;可以在绑定的时候传参,也可以在调用的时候传参
417     // user.bind(lisi, "优酷","youku.com")();  // 优酷youku.com李四
418 
419     /*8.16.2 bind生成一个新的函数*/
420     // 普通函数
421     // let a = function () {};
422     // let b = a;
423     // console.log(a===b); // true
424 
425     // bind函数
426     // let a = function () {};
427     // let b = a.bind();
428     // console.log(a===b); // false
429 
430     /*8.16.3 bind在绑定的时候传参,也可以在调用的时候传参*/
431     // let sum = function (a, b) {
432     //     console.log(a, b);
433     //     return this.f + a + b;
434     // };
435     // // 在绑定的时候传参
436     // let func = sum.bind({f:1},2,3);
437     // console.log(func());     // 2 3    6
438     // // 在调用的时候传参
439     // let func1 = sum.bind({f:4},5);
440     // console.log(func1(6,7)); // 5 6    15
441 
442     /*8.16.4 bind和监听绑定事件一起使用*/
443     // document.querySelector('button').addEventListener('click', function() {
444     //     console.log(this);   // {message: '欢迎!'}
445     //     alert(this.message); // 欢迎!
446     // }.bind({message: "欢迎!"}));
447 
448 </script>
449 </body>
450 </html>

 

posted @ 2022-08-09 13:47  云起时。  阅读(21)  评论(0编辑  收藏  举报