js面试题

1 预编译 GO AO 执行期上下文问题

// GO  a:undefined   test:原来是a+=1 但是被替换掉了 变成 a+=3
 var a = 1  // 此时 GO{a:1}
     function test() {
      a += 1
    }
    test() // GO{a:4}
    function test() {
      a += 3
    }
    test() // GO:{a:7}
    console.log(a);
//     输出 7

考点:预编译(预编译环节,先变量声明提前,再给函数声明赋值,再执行
执行过程中未赋值的声明变量由于声明提前所以忽略)

2 立即执行函数的条件

	 function abc() {
      console.log(2)
    } (1,2,3)  //输出结果为 3

计算机会想办法不报错,然后理解成

	function abc() {
     console.log(2)
   } 

	(1,2,3)  

只有 表达式 才可以变成立即执行函数
何为表达式,可以理解为数字展示,重要的是知道什么不是表达式,至少 函数声明 不是

	function abc() {
     console.log(2)
   }()  // 报错 Uncaught SyntaxError: Unexpected token 

也就是说可以这样

	(function abc() {
     console.log(2)
   }())  
   //2

这样

	(function abc() {
     console.log(2)
   })()  //2

甚至过分到这样

 !function abc() {
     console.log(2)
   }() //2
   
  +function abc() {
    console.log(2)
  }() //2

 -function abc() {
     console.log(2)
   }() //2

再过分点

 1,function abc() {
     console.log(2)
   }()  //2

考点:立即执行函数的执行条件

3 闭包
首先要知道每个对象有scope属性
scope属性的下标指向作用域(执行器上下文)
比如全局的变量 var a=1
那么 window GO 对象会有个a的属性 属性值为1

var a=1,b=2,f="f1"
function fun1 (){
	var c=3
	var d=4
	var f="f2"
}

// 定义一个函数 fun1 那么fun1的 scope[0]指向自己的AO scope[1]指向window GO
fun1.scope[
	AO:{c:3,
		d:4,
		f:"f2"
	},
	GO{
		fun1:function(){...},
		a:1,
		b:2,
		f:"f1"
	}
]
// 此时fun1可以优先使用自己的AO,再考虑GO 并且GO访问不了AO里的属性 
console.log(a)  //1
console.log(f1) //"f1"
console.log(c)  // 报错 : c is not defined

如果在fun1的基础上再声明一个函数fun2,也同理 fun2可以使用 fun,以及GO的参数 但是 fun1和全局无法访问fun2的参数
也就是说fun2可以在fun1的基础上使用fun1的变量,那么把fun2返回出来 就形成闭包 此时可以利用闭包做一个记忆的功能

写一组li 每点击里面的一个能打印出自己的下标

 <ul>
    <li>123</li>
    <li>123</li>
    <li>123</li>
    <li>123</li>
    <li>123</li>
    <li>123</li>
  </ul>

  <script>
    var li = document.getElementsByTagName('li')
    for (var i = 0; i < li.length; i++) {
      (function (j) {
        li[i].onclick = function () {
          console.log(j)
        }
      }(i))
    }// 又或者可以用let,让for的值形成块级作用域,也可以不用闭包

    for(let i=0; i<li.length; i++){
	    li[i].onclick=function(){
	    console.log(i)
    }
  </script>
  • 请问以下表达式的结果是什么

parseInt(3,8)
parseInt(3,2)
parseInt(3,0)

A 3, 3 , 3
B 3, 3, NaN
C 3,NaN,NaN √ parseInt是以第二位数为第一位数的进制, 二进制不可能有3 所以NaN
D other

  • 以下哪些是js typeof 返回的结果

A string √
B array
C object √
D null

array, object, null 经过typeof都返回 字符串object
函数 返回 function 字符串返回 String 数字 Number
undefined 返回 undefined boolean返回boolean
返回的全都是字符串

  • 以下哪些结果为 true

A undefined == null√
B undefined===null
C isNaN(“100”)
D parseInt(“1a”)==1 √

  • 类数组操作
// alibaba 面试题:
	var obj = {
      '2': 'a',
      '3': 'b',
      "length": 2,
      "push": Array.prototype.push
    }
    obj.push("c")
    obj.push("d")
    console.log(obj); // {'2':"c",'3':"d",'length':4}
/*
	//  push 原理
    Array.prototype.push = function (target) {
      this[this.length] = target;
      this.length++
    }
*/
  • 给有序的数组乱序

使用sort排序 在回掉函数里使用随机数return整数或者负数

	arr.sort(function (a, b) {
		return  Math.round(Math.random()*10)/10 -0.5
    })

** 隐式转换**

引用值的隐式类型转换
隐式调用包装类 或string 或number

 []+ "" // ""
 []+ 1 // '1'
 [] + 2 // "2"
 Number([]) // 0
 [] -1 // -1
 []  /2 //0 

{}+1 /1
 Number({})  // 1
 [] ==[] // false 
 [] == {} // false

** 私有化变量**

new出来的只能用自己变量 不会影响构造函数

   function Person(name, age, sex) {
      this.age = age
      this.name = name;
      this.sex = sex
      var a = 0
      function sss() {
        a++;
        console.log(a)
      };
      this.say = sss
    }
    var oPerson = new Person()
    oPerson.say() //1
    oPerson.say()	// 2
    var oPerson2 = new Person()
    oPerson2.say() //1

** delete 删除变量 **

arguments的形参相当于 var 的变量 无法删除 接着程序该怎么执行怎么执行

(function (x) {
      delete x;
      console.log(x)  
    }(1))

** 函数表达式和定义 **

当 一个变量 = 函数时 此时是函数声明 function的名字没有意义

var h = function a() {
      return 1
    }
    typeof a()
// ReferenceError: a is not defined

** div在页面中居中显示 **

绝对定位 left,top 50% margin = -1/2 高,宽
绝对定位 上下左右都是0 marign auto

    div{
      width:200px;
      height:200px;
      position: absolute;
      top:50%;
      left:50%;
      background:slategray;
      margin:-100px 0 0  -100px  ;
    }
    
    div{
      width:200px;
      height:200px;
      position: absolute;
      top:0;
      left:0;
      right: 0;
      bottom: 0;
      background:slategray;
      margin:auto;

    }

** this的终极问题 **

谁调用,this就指向谁, 第三个传递的只是函数方法,没有传递this指向
在某个环境里执行不算被调用 ,this不会改指向

var name = '222';
    var a = {
      name: "111",
      say: function () {
        console.log(this.name);
      }
    }

    var fun = a.say
    fun() // 222
    a.say() // 111

    var b = {
      name: "333",
      say: function (fun) {
        // 如果 (this.fun())调用 那么 { this = b } 
        // 如果没有this 那么谁也没调用,this指向window { this = window }
        // 此时 fun = function () {console.log(this.name)}
        fun()  // 222 
        test() // window  区域执行不算不打点不算被某个函数调用 
      }
    }
    b.say(a.say) // 222
    b.say = a.say
    b.say() // 333
function test(){
	console.log(this)
}

** 阅读代码,写结果 **

即使不用new this也生效会改变window的同名变量

 var foo = 123;
    function print() {
      var   foo = 234;
      this.foo = 567
      console.log(foo); // 没有用this改变指向,所以指向AO的foo
    }
    print() //234 
    console.log(foo); // 567 被内部的this改变

用new 执行print

var foo = 123;
    function print() {
    // 用 new 那么 this = Object.create(price.prototype) 
   //相当于创建了一个空对象=>结果就是一个{undefined}__proto__ 是 price.prototype
    // 此时this 不会改变window的foo
      this.foo = 234; // 给{undefined}赋值为 {foo:234}
      var foo =567 
      console.log(foo); // 567 这个foo只是私有化的变量
    }
    new print() //  用new调用,this不再指向全局,不能改变window.foo
    console.log(foo); // 123
    //  657
    // 123

** 直接执行test 和 new test的执行结果 **

因为new this没有申明a 所以是undefined

   var a = 5
    function test() {
      a = 0;
      cosnole.log(a);
      cosnole.log(this.a);
      var a;
      cosnole.log(a)
    }
    test()  // 050
    new test() // 0 undefined 0
    

** apply call bind **

bind相当于call,改变了this的指向但是不会自动调用函数

    function print() {
      var marty = {
        name: "marty",
        printName: function () {
          console.log(this.name);
        }
      }

      var test1 = { name: "test1" }
      var test2 = { name: "test2" }
      var test3 = { name: "test3" }
      test3.printName = marty.printName
      
      // bind改变了函数的运行环境 不会主动调用printName方法
      // 相当于 {name:123,prinName:function(){cosnole.log(this.name}}
      var printName2 = marty.printName.bind({ name: 123 })

      marty.printName.call(test1) // test1
      // apply传入参数形式为数组,此时并没有传参只是改变指向
      marty.printName.apply(test2)  // test2
      marty.printName(); // marty
      printName2(); // 123
      test3.printName() // test3
    }
    print()

** 作用域改变 **

函数连续调用 内部可以改变外部的变量

    var bar = { a: "002" }
    function print() {
      bar.a = "a";
      Object.prototype.b = 'b';
      return function inner() {
        console.log(bar.a); // a
        console.log(bar.b); // b

      }
    }
    print()()

** 函数的作用域,以及调用 **

   var x = 10
    var obj = {
      x: 30,
      f: function () {
        console.log(this.x);
      }
    }
    function show(f) {
      var that = obj;
      var x = 20;
      f()  // 10 不受x=20影响 因为作用域根据函数定义的地方决定
         // 此时 this指向的是window 
      obj.f()  // 30  被 obj调用 this 指向 obj
      that.f() // 30    
    }
    show(obj.f);



  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值