JavaScript忍者秘籍笔记01之函数
来源:互联网 发布:淘宝学生女装店 知乎 编辑:程序博客网 时间:2024/06/06 10:08
若网络条件允许,可以直接看我的个人博客,可能阅读体验更好
点击查看
函数的独特之处
浏览器的事件轮询是单线程的
函数声明
函数name属性
function isNimble() { return true;}console.log(isNimble.name === 'isNimble'); // truevar canFly = function() { return true;};console.log(canFly.name === 'canFly'); // true ,此处跟原书内容不同,原书内容name为空,实际测试不为空window.wieldsSword = function swingsSword() { return true;};console.log(window.wieldsSword.name === 'swingsSword'); // truevar object2 = { someMethod1: function() {}};object2.someMethod2 = function() {}console.log(object2.someMethod1.name); // 'someMethod1'console.log(object2.someMethod2.name); // ''// 你不能改变一个函数的 name 属性的值, 因为该属性是只读的var object = { // someMethod 属性指向一个匿名函数 someMethod: function() { }};object.someMethod.name = "otherMethod";console.log(object.someMethod.name); // someMethod// Function.bind() 所创建的函数将会在函数的名称前加上"bound "function foo() {}; console.log(foo.bind({}).name); // "bound foo"console.log((new Function).name); // 'anonymous'
更多请参考:Function.name - JavaScript|MDN
函数声明提升
function outer() { console.log(typeof inner === 'function'); // true, 函数声明提升 function inner() {} console.log(window.inner === undefined); // true, inner()不在全局作用域内}outer();
作用域和函数
function outer() { console.log(c); // undefined。变量定义提升,但赋值没有提升 console.log(d); // undefined if(false) { var c = 3; } var d = 4; var d; // 重复声明不影响原值 console.log(c); // undefined,并没有被赋值 console.log(d); // 4}outer();
- 变量定义的作用域在整个函数内,但变量赋值的作用域开始于被赋值的地方,结束于所在函数的结尾,都与代码嵌套无关。
- 命名函数的作用域是指声明该函数的整个函数范围,与代码嵌套无关(机制提升)
- 对于作用域声明,全局上下文就像一个包含页面所有代码的超大型函数
函数调用
function foo() { return this;}console.log(foo() === global); // truevar bar = foo;console.log(bar() === global); // true
使用bar变量调用该函数,该函数也是作为函数进行调用的,而且函数上下文依然是global(在浏览器是window);
小结
- 函数的形参列表和实际参数的长度可以是不同的。
未赋值的参数被设置为undefined。
多出的参数是不会绑定到参数名称的。 - 每个函数调用都会传入两个隐式参数:
arguments,实际传入的参数集合
this,作为函数上下文的对象引用 - 可以用不同的方法进行函数调用,不同的调用机制决定了函数上下文的不同。
作为普通函数进行调用时,其上下文的全局对象(global/window)。
作为方法进行调用时,其上下文是拥有该方法的对象。
作为构造器进行调用时,其上下文是一个新分配的对象。
通过函数的apply()或call()方法进行调用时,上下文可以设置成任何值。
递归
内联命名函数
var bar = function foo() { console.log(foo === bar); // true}bar();console.log(typeof foo); // undefined
- 尽管可以给内联函数进行命名,但这些名称只能在自身函数内部才是可见的。
!!
构造是一个可以将任意JavaScript表达式转化为其等效布尔值的简单方式。eg,!!"a" === true
和!!0 === false
可变长度的参数列表
函数的length属性
函数的length属性等于该函数声明时所要传入的形参数量
function bar(a) {}function foo(a, b, c) {}console.log(bar.length); // 1console.log(foo.length); // 3
- 通过其length属性,可以知道声明了多少命名参数
- 通过
arguments.length
,可以知道在调用时传入了多少参数- 利用参数个数的差异创建重载函数
利用参数的个数进行函数重载
function addMethod(object, name, fn) { var old = object[name]; object[name] = function() { if (fn.length == arguments.length) { return fn.apply(this, arguments); } else if (typeof old === 'function') { return old.apply(this, arguments); } }}var myobj = {};addMethod(myobj, 'a', function() { console.log('0个参数');});addMethod(myobj, 'a', function(n) { console.log('1个参数', n);});addMethod(myobj, 'a', function(n1, n2) { console.log('两个参数', n1, n2);});myobj.a(); // 0个参数myobj.a(1); // 1个参数 1myobj.a(1, 2); // 两个参数 1 2
函数判断
function foo() {}// 第一种,有跨浏览器问题console.log(typeof foo); // function// 更好的解决方法function isFunction(fn) { return Object.prototype.toString.call(fn) === '[object Function]';}console.log(isFunction(foo)); // true
阅读全文
0 0
- JavaScript忍者秘籍笔记01之函数
- 《JavaScript忍者秘籍》笔记
- JavaScript忍者秘籍笔记02之闭包
- JavaScript忍者秘籍笔记03之正则表达式
- JavaScript忍者秘籍笔记04之线程和定时器
- JavaScript忍者秘籍笔记05之跨浏览器策略
- javascript忍者秘籍
- Javascript 进阶知识整理[读Javascript忍者秘籍整理]
- JavaScript创建对象--AngularJs开发秘籍笔记
- JavaScript学习笔记之函数
- JavaScript忍者秘籍——互动出版网
- 概念笔记之[javascript<-1->]函数思想
- Javascript学习笔记(二)Javascript核心之函数
- 《html5秘籍》 笔记
- 【HTML】《HTML5秘籍》笔记
- Javascript学习笔记之函数重载和类型检查
- JavaScript学习笔记(05)之函数的那点事
- 《Javascript权威指南》学习笔记之六:自定义函数
- TCP和UDP的区别
- python3中的基础类型
- Python 5) 基础 继承
- 在 ant build时“找不到符号”解决方法(待验证)
- [C/C++标准库]_[初级]_[移除反转枚举reverse_iterator]
- JavaScript忍者秘籍笔记01之函数
- go install 基本使用
- 51Nod-1137-矩阵乘法
- 1049. 数列的片段和(20)
- 最大上升子序列(从前往后) nlogn 和最大上升序列(从后往前)
- 数组·1·素数对猜想
- 用Python+StanfordCoreNLP做中文命名实体分析
- path-sum
- mybatis-config.xml配置文件