2.预编译的执行时间、步骤是什么?有几种?

  1. 执行时间:执行在函数执行的前一刻
    2. 四部曲:
    a) 创建AO对象(activation object 执行期上下文)
    b) 找形参和变量声明;将变量和形参名作为AO属性名,值为undefined
    c) 将实参值和形参统一
    d) 在函数题里面找函数声明,值赋予函数体

    3. 两种,上面是在函数中,还有一种是在全局中
    a) 创建GO对象(Global Object)=== window
    b) 找变量声明;将变量名作为AO属性名,值为undefined
    c) 在函数题里面找函数声明,值赋予函数体
    4. function sum () { console.log(a) }
    a,就近原则,先在函数里找,如果没有,就在window中找。

    3.预编译题目

    第一题:

    1. function fn(a) {
    2. console.log(a);
    3. var a = 123;
    4. console.log(a);
    5. function a() {}
    6. console.log(a);
    7. var b = function() {}
    8. console.log(b)
    9. function d() {}
    10. }
    11. fn(1);

    第二题:

    1. function test(a,b) {
    2. console.log(a);
    3. c = 0;
    4. var c;
    5. a = 3;
    6. b = 2;
    7. console.log(b);
    8. function b() { }
    9. function d() { }
    10. console.log(b);
    11. }
    12. test(1)
    13. console.log(h); //123
    14. console.log(c); //报错
    15. console.log(a); //报错
    16. console.log(b); //报错
    答案: ƒ a() { }、 123、 123、 ƒ() { } 、1、 2、 2
  1. a = 100;
  2. function demo(e) {
  3. function e() {}
  4. arguments[0] = 2;
  5. console.log(e);
  6. console.log(a);
  7. console.log(Number(a));
  8. console.log(Boolean(a));
  9. if(a) {
  10. var b = 123;
  11. function c() {}
  12. }
  13. var c;
  14. a = 10;
  15. var a;
  16. console.log(b);
  17. f = 123;
  18. console.log(c);
  19. console.log(a);
  20. }
  21. var a;
  22. demo(1);
  23. console.log(a);
  24. console.log(f);
  1. 2undefinedNaNfalse undefinedundefined10100123


4.类型转换题目

  1. var demo = false == 1;
    console.log(demo);
    2. if(typeof(a)&&-true + (+undefined) + “”) {
    console.log(“基础扎实”);
    }
    3. if(11 + “11” * 2 == 33) {
    console.log(“基础扎实”);
    }
    4. !!” “ + !!”” - !!false
    1 + 0 - 0
    Boolean(document.write(“你觉得能打印,你就是猪”));

    1:先判断 false ==1 得到 false ,然后赋值给demo
    2:typeof(a) 得到 “undefined”, -true得到-1(正负号会隐形转换Number类型),+undefined也会转换Number类型,得到的是NaN—Number类型,加上后面的+“”,变成字符串“NaN”,所以最后是字符串“undefined”+“NaN”。 true
    3.乘除号会进行隐性Number转换,最后得到true
    4.双非不用管 “ ”是true,“”是false 所以是1+0-0。 最后面是false

5.css都有什么选择器?优先级是什么?

1.标签选择器 p ,div 等
2.id选择器,#first 只能用一次
3.后代选择器, p a ——选择所有p标签内的所有a标签
4.子选择器 p>a 离父亲最近的那个儿子,孙子不算
5.并集选择器 .box , p , h3 用逗号
6.交集选择器 a.special —-a标签中类名为special的标签(注意这里面既有标签也有类名)

选择器的优先级
id选择器>类选择>标签选择器
根据权重+继承性来选择
一般规定id为100,类10,标签为1

  1. <ul class="ul-item">
  2. <li>
  3. <p>文字的颜色到底是什么颜色?</p>
  4. </li>
  5. </ul>
  6. .ul-item li{
  7. color: blue;
  8. }
  9. p{
  10. color: red;
  11. }

什么颜色?答案是红色,虽然10+1>1,应该是蓝色。但为什么是红色?
因为他没有选中,没有选中权重再大也无济于事。但是如果把p去掉是什么颜色?
是蓝色,因为这时候是继承性在发挥作用

6.作用域是什么?和作用域链题目

  1. function a() {
  2. function b() {
  3. function c() {}
  4. c()
  5. }
  6. b()
  7. }
  8. a()
  1. a defined a.[[scope]] -- > 0 : GO
  2. a doing a.[[scope]] -- > 0 : aAO
  3. 1 : GO
  4. b defined a.[[scope]] -- > 0 : aAO
  5. 1 : GO
  6. b doing a.[[scope]] -- > 0 : bAO
  7. 1 : aAO
  8. 2 : GO
  9. c defined a.[[scope]]-- > 0 : aBO
  10. 1 : aAO
  11. 2 : GO
  12. c doing a.[[scope]]-- > 0 : cAO
  13. 1 : bAO
  14. 2 : aAO
  15. 3 : GO

如上,在定义和执行时,他的作用域是不一样的,如果不执行,那么将不会生成自己的执行上下文AO,比如function b,如果b不执行,那么b里面一切东西就是封闭的,不会被看到,只有b执行的时候,才会生成AO,然后才能看到里面的东西。
理解这句话:b不执行的时候,他的作用域和a执行时是一样的
而且也说明了,一个变量,总是顺着作用域链,从小到大寻找。

7.作用域和作用域链题目

  1. function a() {
  2. function b() {
  3. var bbb = 234;
  4. console.log(aaa);
  5. }
  6. var aaa = 123;
  7. return b;
  8. }
  9. var glob = 100;
  10. var demo = a();
  11. demo();

当var demo=a()时,a执行,此时a的作用域是AO和GO,执行完毕后,a销毁(指向AO和GO的引用线斩断),但是AO和GO却不会消失,因为a返回了b,此时b指向AO和GO,所以AO和GO不会消失。当b执行的时候,会生成自己的AO,但是a的AO和GO仍然在,也就说,b会有三个作用域:bAO、aAO,GO。 所以答案是 123;

8.更深一点的题目

  1. function a() {
  2. var num = 100;
  3. function b() {
  4. num++;
  5. console.log(num);
  6. }
  7. return b;
  8. }
  9. var demo = a()
  10. demo();
  11. demo();

同上一题,a执行完后,a被销毁,但是aAO还在,并且不管b(demo)重新调用多少次,所有的b都共同用同一个aAO,(不过每个b会单独生成一个专属bAO),所以答案是101,102

9.立即执行函数执行时会忽略函数名什么意思?

  1. var test = function () {
  2. console.log('a');
  3. }();
  4. console.log(test);

这时候test就不会输出,因为一旦一个函数被立即执行,就会忽略他的函数名字。
所以这里的test就没有了。
注意,这时候输出test是undefined
而test()会报错

  1. +function test() {
  2. console.log("a")
  3. }();
  4. test()

这时候会执行吗?会,因为前面有+号,所以就是表达式了,所以可以执行
+ - ! 可以
*/ 不行
&& 和 || 可以,但是前面得放东西
|| function test() {}
得放东西。
下面的test()会执行吗,不会。因为立即执行函数的执行完就被销毁了,而且他的函数名被忽略了

10.立即执行函数的两种写法是什么?

  1. function(){}() //函数不会执行
  2. (function (){}()) //W3C建议第一种
  3. (function (){})()

记忆:第一种是函数加()表示立即执行,然后整体加(),变成表达式
第二种是函数整体加括号,表示这是一个函数表达式,然后最后加()执行
总结:两种方法都必须有一个括号变成表达式,不同的是执行括号可以放在里面,也可以放在外面

一个有趣的结果:

  1. function test(a, b, c, d) {
  2. console.log(a + b + c + d);
  3. }();

这时候会报错:而且是全局扫描时,出错,因为这不符合语法规范。

  1. function test(a, b, c, d) {
  2. console.log(a + b + c + d);
  3. }
  4. (1, 2, 3, 4);

这个时候,不会报错,但是执行之后,什么也不显示,为什么?
其实应该报错,但是系统识别之后,为了能够尽量不报错,会把这段代码识别成这样:

  1. function test(a, b, c, d) {
  2. console.log(a + b + c + d);
  3. }
  4. (1, 2, 3, 4);

两个代码没有任何关系。

11.闭包。最后会输出什么?为什么?

一道关于闭包的题:函数保存到了外面

  1. function test() {
  2. var arr = [];
  3. for (var i = 0; i < 10; i++) {
  4. re[i] = function () {
  5. console.log(i + " ");
  6. }
  7. }
  8. return arr;
  9. }
  10. var myArr = test();
  11. for (var i = 0; i < 10; i++) {
  12. myArr[i]();
  13. }

最后会输出10个10。
那么怎样才能让他从0输出成10呢?立即执行函数+闭包

  1. function test() {
  2. var arr = [];
  3. for (var i = 0; i < 10; i++) {
  4. (function (j) {
  5. arr[j] = function () {
  6. console.log(j + " ");
  7. }
  8. }(i))
  9. }
  10. return arr;
  11. }
  12. var myArr = test();
  13. for (var i = 0; i < 10; i++) {
  14. myArr[i]();
  15. }

转化的逻辑是什么?很明显,第一个是多个函数公用一个testAO,只需要给他们每一个加一个自己的AO就好了。