js面试题 隐式转换、原型链

js面试题 隐式转换、原型链

1. 分析代码,请问执行结果是什么?
var name = "World!";
(function () {
    var name;
    if (typeof name === 'undefined') {
        name = 'Jack';
        console.log('Goodbye' + name);
    } else {
        console.log('hello' + name);
    }
})();
分析:

变量声明提升,JS代码分为存储模块和执行模块。当匿名自调用函数中, 有该变量(和全局变量同名的变量)时,在自身查找,有变量查看是否赋值,赋值直接输出,没有就找全局。因为js是单线程执行var name当前没有赋值,所以类型为undefined

结果:Goodbye Jack


2. 考察Math、call、apply

语句var arr=[a,b,c,d];执行后,数组arr中每项都是一个整数,下面得到其中最大整数语句正确的是哪几项?(多选)

A. Math.max(arr)
B. Math.max(arr[0], arr[1], arr[2], arr[3])
C. Math.max.call(Math, arr[0], arr[1], arr[2], arr[3])
D. Math.max.apply(Math,arr)
分析:

Math.max(args...)传入参数是任意数量的值
A. 错误,不能传入数组
B. 正确
C. 正确,call()可以传入任意多个参数
D. 正确,apply()第二个参数以数组形式传递

结果:B、C、D


3. 分析代码,请问执行结果是什么?
var A = {n: 4399};
var B =  function(){this.n = 9999};
var C =  function(){var n = 8888};
B.prototype = A;
C.prototype = A;
var b = new B();
var c = new C();
A.n++
console.log(b.n);
console.log(c.n);
分析:

主要考察的是原型链,先查看自身是否有,没有找原型,原型也没有找Object,再找不到就是undefined。
1.console.log(b.n);
在查找b.n是首先查找 b 对象自身有没有 n 属性,如果没有会去原型(prototype)上查找,当执行var b = new B()时,函数内部this.n=9999(此时this指向 b) 返回b对象,b对象有自身的n属性,所以返回 9999。
2.console.log(c.n);
同理,当执行var c = new C()时,c对象没有自身的n属性,向上查找,找到原型 (prototype)上的 n 属性,因为 A.n++(此时对象A中的n为4400), 所以返回4400。

结果:9999、4400


4. 分析代码,请问执行结果是什么?
var arr=[{a:1},{}];
arr.forEach(function(item,index){
    item.b=index;
});
console.log(arr);
分析:

forEach()方法是对数组中的每一项运行给定函数,回调函数的参数item为数组当前项,index为当前索引。
这道题就是把数组每一项添加属性 b,并且属性 b 的值为当前项的数组索引值。
然后,forEach()方法没有返回值,所以不能将arr.foreach()像其他数组迭代方法那样赋值给某一个变量。

结果:[{a:1,b:0},{b:1}]


5. (函数定义方式)下列代码中,请分别归类三种函数定义方式:函数声明、函数表达式、构造函数
var sum = new Function('a','b','return a+b')
var sum = function(a,b){ return a+b }
function sum(a,b){ return a+b }
分析:

js函数定义的几种方式如下表:

定义方法代码块
函数声明function sum(a,b){ return a+b }
函数表达式var sum = function(a,b){ return a+b }
构造函数var sum = new Function(‘a’,‘b’,‘return a+b’) //不推荐使用,影响函数解析性能

结果:构造函数、函数表达式、函数声明


6. (this指向)请问以下代码输出结果是什么?
var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log(this.foo);  
        console.log(self.foo);  
        (function() {
            console.log(this.foo);  
            console.log(self.foo);  
        }());
    }
};
myObject.func();
分析:

这道理的关键就在于,方法/函数是由谁调用的,那么其内部的this就指向谁
首先func是由myObject调用的,this指向myObject
又因为var self = this;所以self指向myObject
这个立即执行匿名函数表达式是由window调用的,this指向window 。
立即执行匿名函数的作用域处于myObject.func的作用域中,在这个作用域找不到self变量,沿着作用域链向上查找self变量,找到了指向 myObject对象的self

所处域this指向
windowwindow
普通函数window
构造函数指向类的实例对象
定时器window
自调用函数window

结果:bar bar undefined bar


7. 请问以下代码输出结果是什么?
var x = new Boolean(false);
if (x) {
    alert('hi');
}
var y = Boolean(0);
if (y) {
    alert('hello'); 
}
分析:

这道题考察了JS的类型转换,这里的var x是一个对象,任何对象转为布尔值,都为得到true
题目的第二部分,一定要注意 y = Boolean(0),而不是 y = new Boolean(0)。这两个有很大区别,用new调用构造函数会新建一个布尔对象,此处没有加new,进行的是显示类型转换,所以就是false

结果:hi


8. 请问以下代码输出结果是什么?
var value = 0;
console.log(value != '0' ? 'nonzero' : 'zero');
console.log('Value is ' + (value != '0') ? 'nonzero' : 'zero');
分析:

这道题考察的是第二个console.log中运算符的优先级,加号优先级高于三目运算,低于括号。 所以括号中无论真假,加上前边的字符串都为 true,三目运算为true是输出nonzero

结果:zero、nonzero


如有问题,请在评论中指出,我们互相学习,一起进步!
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
原型链JavaScript中非常重要的一个概念,它是实现继承的主要方法之一。在JavaScript中,每个对象都有一个原型对象,而原型对象也可以有自己的原型对象,这样就形成了一个原型链。当我们访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,就会去它的原型对象中查找,如果还没有,就会去原型对象的原型对象中查找,直到找到该属性或方法或者到达原型链的顶端为止。 下面是一个简单的例子,演示了原型链的基本概念: ```javascript function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function() { console.log("Hello, my name is " + this.name); }; function Student(name, age, grade) { Person.call(this, name, age); this.grade = grade; } Student.prototype = Object.create(Person.prototype); Student.prototype.constructor = Student; Student.prototype.sayGrade = function() { console.log("My grade is " + this.grade); }; var student = new Student("Tom", 18, 3); student.sayHello(); // 输出:Hello, my name is Tom student.sayGrade(); // 输出:My grade is 3 ``` 在上面的例子中,我们定义了一个`Person`构造函数和一个`Student`构造函数,`Student`构造函数继承自`Person`构造函数。我们通过`Object.create`方法将`Student`的原型对象指向`Person`的原型对象,这样就形成了一个原型链。当我们调用`student.sayHello()`方法时,由于`student`对象本身没有`sayHello`方法,就会去它的原型对象`Person.prototype`中查找,找到了该方法并执行。当我们调用`student.sayGrade()`方法时,由于`student`对象本身没有`sayGrade`方法,就会去它的原型对象`Student.prototype`中查找,找到了该方法并执行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mossbaoo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值