js基础知识练习
目录
- 函数声明和函数表达式
- 声明前置
- arguments
- 函数的”重载”
- 作用域问题
- 匿名函数
- 闭包
- 代码实例
- 函数参数和arguments
- 返回参数的平方和
- 函数内重写对象
函数声明和函数表达式
函数声明
function functionName(parameters) {
// body
}
函数声明后不会立即执行,会在我们需要的时候调用到。
函数表达式
var x = function (parameters) {
// body
};
js 函数可以通过一个表达式定义.
函数表达式可以存储在变量中
函数表达式与函数声明的区别
最主要区别是函数名称
在函数表达式中可省略函数声明,从而创建匿名函数
声明前置
变量的声明前置
console.log(a)
var a = 1
输出结果
undefined
代码分析
- 由上到下执行代码之前,解析器会先找关键字var,找到了var a,就提升var a并将a初始化为undefined
- 再由上往下执行,读到consolo.log(a),控制台打印出来的就是undefined
- 接着给变量a赋值为1,如果这个时候后面再加一句consolo.log(a),那么控制台就会多打印出一个1
函数的声明前置
func()
function func() {
console.log("hello world")
}
输出结果
hello world
代码分析
- 找到所有用function声明的变量,在环境中创建这些变量
- 将这些变量初始化并赋值为function(){console.log(“hello world”)}
- 开始执行代码a()
arguments
arguments是什么
一个对应于传递给函数的参数的类数组对象。
arguments知识点
- arguments对象是所有(非箭头)函数中都可用的局部变量.
- 可以使用arguments对象在函数中引用函数的参数, 引用方式和数组相同.
- 可以使用Array.from()方法或扩展运算符将参数转换为真实数组.
函数的”重载”
重载
一个函数通过不同参数列表来实现各个功能,叫函数重载
js中的”重载”
js中不存在函数重载的概念
var override = function () {
switch (arguments.length) {
case 0 :
console.log("0");break;
case 1 :
console.log("1");break;
case 2 :
console.log("2");break;
}
};
override("hv", "ge")
override("xyhv")
override()
输出结果
2
1
0
代码分析
这是js实现重载的传统方法之一
作用域问题
全局作用域
在代码中任何地方都能访问到的对象拥有全局作用域
拥有全局作用域的情形
- 最外层函数和在最外层函数外面定义的变量拥有全局作用域
- 所有未定义直接赋值的变量自动声明为拥有全局作用域
function doSomething(){
var authorName="星辉"
blogName="星辉的博客"
}
// blogName拥有全局作用域,而authorName在函数外部无法访问到
- 所有window对象的属性拥有全局作用域
局部作用域
局部作用域一般只在固定的代码片段内可访问到
拥有局部作用域的情形
- 函数内部
js没有块级作用域
例如if条件语句, 就不算一个独立的作用域
变通方式
通过自执行函数创建临时作用域
function foo() {
var x = 1;
if (x) {
(function () {
var x = 2;
// some other code
}());
}
console.log(x)
}
foo()
输出结果
1
匿名函数
定义
没有函数名的函数
匿名函数的创建
- 第一种方式
var mi = function(x) { return 2* x; }
“=”右边的函数就是一个匿名函数,创造完毕函数后,又将该函数赋给了变量mi
- 第二种方式
(function(x, y){
alert(x + y);
})(2, 3);
在第一个括号内创建了一个匿名函数,第二个括号用于调用该匿名函数,并传入参数
闭包
定义
函数的嵌套,内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕
作用
保证内部作用域中的引用不会被垃圾回收器回收
闭包的方式构建类
var object=function(mod){
var field1;
var method1=function(){
};
return{
field1:field1,
method1:method1
}
}(model);
代码解析
- 这样可以很好的保护私有成员变量和方法
- 可以通过以上方式注入实参
代码实例
函数参数和arguments
function getInfo(name, age, sex) {
console.log('name', name)
console.log('age', age)
console.log('sex', sex)
console.log(arguments)
arguments[0] = 'valley'
console.log('name', name)
}
getInfo('小辉', 18, '男')
getInfo('辉辉', 16)
getInfo('男')
输出结果
name 小辉
age 18
sex 男
Arguments(3) ["小辉", 18, "男"]
name valley
name 辉辉
age 16
sex undefined
Arguments(2) ["辉辉", 16]
name valley
name 男
age undefined
sex undefined
Arguments ["男"]
name valley
代码分析
- Js是弱数据类型, 实参少了则按顺序给形参赋值
- arguments 即获取了所有的实参, 可按数组的方式调用
- 可更改arguments,从而更改相应的值
返回参数的平方和
function sumOfSquares(){
var sum = 0
var arr = [...arguments]
for (var i = 0; i < arr.length; i++) {
sum += arr[i] * arr[i]
}
return sum
}
var result = sumOfSquares(2, 3, 4)
var result2 = sumOfSquares(1, 3)
console.log(result)
console.log(result2)
输出结果
29
10
代码分析
- 不要在形参中写arguments,否则js会把其当作形参变量
- arguments是类数组对象,转为数组除了需要拓展运算符,还有数组的中括号
函数内重写对象
function setName(obj) {
obj.name = 'Nicholas'
obj = new Object()
obj.name = 'Greg'
}
var person = new Object()
setName(person)
console.log(person.name)
输出结果
Nicholas
代码分析
在函数内部重写 obj 时, 这个变量引用的是一个局部对象
这个局部对象会在函数执行完毕后立即被销毁