1、----------------------------
// 解析器:
// 预解析 全局作用域
// 先找var 、function 和参数
// 找到var和function之后,会把var和function提前
//num fun
// 从上到下一行一行执行代码
// num = 10;
// fun();
// 执行到fun后,进入局部作用域
// 预解析
// num
// 从上到下一行一行执行代码
var num;
function fun() {
var num;
console.log(num);
num = 20;
}
num = 18;
// var num = 10;
// fun();
// function fun() {
// console.log(num);
// var num = 20;
// }
2、-------------------------------------------
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
var a;
function f1() {
var b;
var a;
b = 9;
console.log(a);
console.log(b);
a = '123';
}
a = 18;
f1();
var a=18;
function f1(){
//先在当前作用域下找变量a,如果当前作用域没有变量a,会去上一级作用域找变量a。
// 如果找到了,就获取a的值。如果都找不到,会显示a is not defined。
console.log(a);
}
f1();
3、------------------------------------
// 解析器
// 全局作用域 预解析 var function 参数
// 预解析
// function f1()
// 一行一行执行代码
// f1() 局部作用域
// 预解析
// var a;
// 一行一行解析代码
function f1(){
// a 局部变量
// b c全局变量
var a;
a=b=c=9;
console.log(a);
console.log(b);
console.log(c);
}
f1();
console.log(c);
console.log(b);
console.log(a);
// f1();
// console.log(c);
// console.log(b);
// console.log(a);
// function f1(){
// var a=b=c=9;
// console.log(a);
// console.log(b);
// console.log(c);
// }
``
```javascript
4、
var n = 10;
function outer(){
function inner(){
function center(){
console.log(n);
}
center();
}
inner();
var n = 15;
}
outer(); //=> undefined
5、
function foo() {
var a = 2;
function baz() {
console.log( a );
}
return baz;
}
var fn = foo()
fn();//2
6、
var name = "小红";
function doSomething(){
var anotherName = "小黑";
function showName(){
console.info(name)
console.info(anotherName)
}
showName();
}
console.info(name);//小红
console.info(anotherName);//【脚本出错】
doSomething();//小红---小黑
showName();//【脚本出错】
7、问题: 范围(Scope)
思考以下代码:
(function() {
var a = b = 5;
})();
console.log(b);
控制台会打印出什么?
答案
上述代码会打印出5。
(1)在立即执行函数表达式(IIFE)中,有两个命名,但是其中变量是通过关键词var来声明的。这就意味着a是这个函数的局部变量。与此相反,b是在全局作用域下的。
(2)在函数中他没有使用_“严格模式”_ (‘use strict’😉。如果 严格模式开启,那么代码就会报出未捕获引用错误(Uncaught ReferenceError):b没有定义。
// 严格模式写法
(function() {
'use strict';
var a = window.b = 5;
})();
console.log(b);
8、问题: 创建 “原生(native)” 方法
在String对象上定义一个repeatify函数。这个函数接受一个整数参数,来明确字符串需要重复几次。这个函数要求字符串重复指定的次数。举个例子:
console.log('hello'.repeattify(3));
应该打印出 hellohellohello.
答案
一种可能的实现如下所示:
String.prototype.repeatify = String.prototype.repeatify || function(times) {
var str = '';
for (var i = 0; i < times; i++) {
str += this;
}
return str;
};
这个问题测试了开发人员对于javascript中继承的掌握,以及prototype这个属性。这也验证了开发人员是否有能力扩展原生数据类型的功能(虽然不应该这么做)。
这个问题的另一个重点是验证你是否意识到并知道如何避免覆盖已经存在的函数。这可以通过在自定义函数之前判断该函数是否存在来做到。
String.prototype.repeatify = String.prototype.repeatify || function(times) {/* code here */};
当你需要为旧浏览器实现向后兼容的函数时,这一技巧十分有用。
9、问题: 变量提升(Hoisting)
执行以下代码会有什么结果?为什么?
function test() {
console.log(a);
console.log(foo());
var a = 1;
function foo() {
return 2;
}
}
test();
答案
这段代码的执行结果是undefined 和 2。
这个结果的原因是,变量和函数都被提升了(hoisted)。因此,在a被打印的时候,它已经在函数作用域中存在(即它已经被声明了),但是它的值依然是 undefined。换言之,上述代码和以下代码是等价的。
function test() {
var a;
function foo() {
return 2;
}
console.log(a);
console.log(foo());
a = 1;
}
test();
10、问题: this在javascript中是如何工作的
以下代码的结果是什么?请解释你的答案。
var fullname = 'John Doe';
var obj = {
fullname: 'Colin Ihrig',
prop: {
fullname: 'Aurelio De Rosa',
getFullname: function() {
return this.fullname;
}
}
};
console.log(obj.prop.getFullname());
var test = obj.prop.getFullname;
console.log(test());
答案
上面的代码打印出Aurelio De Rosa和John Doe。原因是在 JavaScript 中,一个函数的上下文环境,也就是this关键词所引用对象,是依赖于函数是如何被调用的,而不是依赖于函数如何b被定义的。
在第一个console.log()调用中, getFullname()是作为obj.prop的函数被调用的。因此,这里的上下文环境指向后者并且函数返回this对象的 fullname属性。相反,当 getFullname() 被赋为test变量的值时,那个语境指向全局对象(window)。这是因为,test被隐式设置为全局对象的属性。因此,函数调用返回window的fullname属性值,在此段代码中,这个值是通过第一行赋值语句设置的。