1. 立即执行函数表达式是什么?有什么作用?
(function(){
console.log('我是立即执行函数')
})()
-
立即执行函数就是
- 声明一个匿名函数
- 马上调用这个匿名函数
-
那么为什么还要用另一对括号把匿名函数包起来呢?
- 其实是为了兼容 JS 的语法。如果我们不加另一对括号,直接写成
function(){alert('我是匿名函数')}()
浏览器会报语法错误。所以我们在外面加一个括号()
让浏览器觉得我们语法正确.知道这是一个函数,需要调用
- 其实是为了兼容 JS 的语法。如果我们不加另一对括号,直接写成
-
作用?
- 立即执行函数可以形成一个作用域,和全局隔开,不会污染全局,另一方面也是防止命名冲突的影响
2. 求n!,用递归来实现
function factorial(n){
if(n === 1){
return 1
}
return n * factorial(n-1)
}
factorial(n)
3. 以下代码输出什么?
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('饥人谷', 2, '男'); //name: 饥人谷 age: 2 sex: 男
getInfo('小谷', 3); //name: 小谷 age: 3 sex: undefined
getInfo('男'); //name: 男 age: undefined sex: undefined
4. 写一个函数,返回参数的平方和?
function sumOfSquares(){
}
var result = sumOfSquares(2,3,4)
var result2 = sumOfSquares(1,3)
console.log(result) //29
console.log(result2) //10
答案:
function sumOfSquares(){
var length = arguments.length,
result = 0,
parameter
for(var i = 0; i< length; i++){
parameter = arguments[i]
result += parameter*parameter
}
return result
}
sumOfSquares(2,3,4) //29
sumOfSquares(1,3) //10
5. 如下代码的输出?为什么
console.log(a); //undefined
var a = 1;
console.log(b); //error 不存在
==>
var a
console.log(a)
a = 1
console.log(b)
6. 如下代码的输出?为什么
sayName('world'); //hello world
sayAge(10); //error 不是一个函数
function sayName(name){
console.log('hello ', name);
}
var sayAge = function(age){
console.log(age);
};
==>
function sayName(name){
console.log('hello ', name);
}
var sayAge
sayName('world');
sayAge(10);
sayAge = function(age){
console.log(age);
};
7. 如下代码输出什么? 为什么
var x = 10
bar() //10
function foo() {
console.log(x)
}
function bar(){
var x = 30
foo()
}
1. bar()在全局作用域中没有找到值,然后在函数bar()中寻找,
2. 找到了一个foo()函数的调用,然后取函数foo()里找,要打印x,
3. 但函数foo()里没有定义x的值,去上一层作用域得到x=10,所以bar() =10
8. 如下代码输出什么? 为什么
var x = 10;
bar() //30
function bar(){
var x = 30;
function foo(){
console.log(x)
}
foo();
}
这一题和上一题的区别是函数foo()和函数bar()不是同级关系了
1. 我们先在函数bar()里找,找到了foo(),
2. 然后在foo()里找,打印x,x在foo()里找不到x的值
3. 在上一层的作用域里找到了var x = 30, 所以bar()值为30
9. 如下代码输出什么? 为什么
var a = 1
function fn1(){
function fn2(){
console.log(a)
}
function fn3(){
var a = 4
fn2()
}
var a = 2
return fn3
}
var fn = fn1()
fn() //输出2
1. 先去fn1()作用域去找,在fn1()函数里, return fn3,fn2,fn3同级,
2. 去fn3作用域里调用了函数fn2()
3. 我们再去fn2()作用域中,打印a,去上一级作用域中fn1()中找到var a = 2
4. 所以fn()输出2
10. 如下代码输出什么? 为什么
var a = 1
function fn1(){
function fn3(){
var a = 4
fn2()
}
var a = 2
return fn3
}
function fn2(){
console.log(a)
}
var fn = fn1()
fn() //输出1
1. 先去fn1()作用域去找,在fn1()函数里, return fn3,
2. 我么能进入到fn3()作用域中,调用fn2()
3. 因为fn1 和 fn2同级,所以在fn2()中打印a,就要在全局作用域中找a
4. 全局作用域var a = 1
5. 所以结果是1
11. 如下代码输出什么? 为什么
var a = 1
function fn1(){
function fn3(){
function fn2(){
console.log(a)
}
fn2()
var a = 4
}
var a = 2
return fn3
}
var fn = fn1()
fn() //输出undefined
1. 进入fn1()作用域中,return fn3() ,
2. 进入fn3()作用域看到调用调用函数fn2(),
3. 在fn3()作用域中找到fn2(),打印a,去上一级作用域中找a
4. var a = 4,由于变量声明前置 ==> var a
5. 结果是undefined
12.如下代码输出什么?为什么
var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2); //false obj1和obj2指向不同的地址,所以不相等
console.log(obj1 = obj2); //{a:1,b:2} obj2的值赋值给obj1
console.log(obj1 == obj2); //true 上一步赋值是将obj2的位置复制给obj1,于是obj1和obj2指向同一块内存,所以相等
13. 如下代码输出什么? 为什么
var a = 1
var c = { name: 'jirengu', age: 2 }
function f1(n){
++n
}
function f2(obj){
++obj.age
}
f1(a)
f2(c)
f1(c.age)
console.log(a) //输出1 相当于声明了一个变量n加了1,但是对a没有任何影响
console.log(c) //输出{name: "jirengu", age: 3} 相当于把c的值赋给了obj,指向同一个地址,c.age+1,所以c得值也加了1
14.写一个浅拷贝函数
var shallowCopy = function(obj) {
// 只拷贝对象
if (typeof obj !== 'object') return;
// 根据obj的类型判断是新建一个数组还是对象
var newObj = obj instanceof Array ? [] : {};
// 遍历obj,并且判断是obj的属性才拷贝
for (var key in obj) {
//hasOwnProperty:用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
15.写一个深拷贝函数
//递归
function deepClone(oldObj){
//判断是不是对象
if(typeof oldObj !== 'object'){
return oldObj
}
//判断是否是内置对象类型
if(oldObj instanceof Array){
var newObj = []
}else{
var newObj = {}
}
//for- in用来枚举对象的属性
for(var key in oldObj){
//判断对象里面的属性是否是对象类型
if(typeof oldObj[key] === 'object'){
//是的话,在拷贝一次
newObj[key] = deepClone(oldObj[key])
}else{
//不是,把oldObj赋值给new
newObj[key] = oldObj[key]
}
}
return newObj
}