js常见问题总结概括

1、使用 typeof bar === "object" 来肯定 bar 是不是对象的潜在陷阱是什么?如何避免这个陷阱?

首先typeof bar === "object"是检测bar是不是对象的可靠方法,但在javascriptnull也被认为是对象,所以如下代码在控制台中将输出true:javascript

var bar = null;
console.log(typeof bar == "object"); 

因此知道了null的问题,同时检测bar是不是null,就能够避免这一问题啦:java

console.log((bar !== null) && (typeof bar === "object")); 

bar是一个数组的时候,例如,当var bar = []的时候;在不少状况下,这是指望行为,由于数字是真正的对象,但若是你想数组也返回false时,能够修改上述方案:数组

console.log((bar !== null) && (typeof bar === "object") && (toString.call(bar) !== "[object Array]")); 

2、下面的代码将输出什么到控制台?为何?

(function(){ var a = b = 3; })(); console.log(typeof a == "undefined"); console.log(typeof b == "undefined"); 

var a = b = 3;这句代码等同于:b = 3; var a = b;这时候变量b是不加var声明的变量,也就是全局变量,在函数内部没有var声明的变量是隐式全局变量。因此控制台打印的结果为:truefalse。 若是再深刻一步:在严格模式(使用use strict),结果又会怎样? 在严格模式下运行的结果是:报错:b is not undefined;这正是严格模式的特色,避免没必要要的bug(避免全局变量污染)。安全

3、关于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(); 

在外部函数中,thisself都是指向myObject,因此二者均可以正确的引用和访问foo,在内部函数中,this再也不指向myObject,结果是this.foo没有在内部函数中被定义。在ECMA5以前,在内部函数中的this将指向全局的window对象;反之,由于做为ECMA5,内部函数中的功能this是未定义的。因此控制台将输出:bar ;bar ;undefined ;bar ;bash

4、use strict有什么意义和好处?

use strict 是一种在JavaScript代码运行时自动实行更严格解析和错误处理的方法。 严格模式的一些主要优势包括:函数

1.使调试更加容易。那些被忽略或默默失败了的代码错误,会产生错误或抛出异常,所以尽早提醒你代码中的问题,你才能更快地指引到它们的源代码。测试

2.防止意外的全局变量。若是没有严格模式,将值分配给一个未声明的变量会自动建立该名称的全局变量。这是JavaScript中最多见的错误之一。在严格模式下,这样作的话会抛出错误。字体

3.消除this强制。若是没有严格模式,引用null或未定义的值到this 值会自动强制到全局变量。这可能会致使许多使人头痛的问题和让人巴不得拔本身头发的bug。在严格模式下,引用 null或未定义的this值会抛出错误。ui

4.不容许重复的属性名称或参数值。当检测到对象中重复命名的属性,例如: var object = {foo: "bar", foo: "baz"};) 或检测到函数中重复命名的参数时,例如: function foo(val1, val2, val1){}) 严格模式会抛出错误,所以捕捉几乎能够确定是代码中的bug能够避免浪费大量的跟踪时间。this

5.使eval()更安全。在严格模式和非严格模式下,eval() 的行为方式有所不一样。最显而易见的是,在严格模式下,变量和声明在eval() 语句内部的函数不会在包含范围内建立(它们会在非严格模式下的包含范围中被建立,这也是一个常见的问题源)。

6.在delete使用无效时抛出错误。delete 操做符(用于从对象中删除属性)不能用在对象不可配置的属性上。当试图删除一个不可配置的属性时,非严格代码将默默地失败,而严格模式将在这样的状况下抛出异常。

5、当心javascript自动插入分号机制?看下面的代码,它们会返回什么?

function foo1(){ return { bar:"hello" }; } function foo2(){ return { bar:"hello" }; } console.log("foo1 returns:"); console.log(foo1()); consoel.log("foo2 returns:"); console.log(foo2()); 

以上代码将会打印出:

foo1 returns:
Object {bar:"hello"} foo2 returns: undefined 

缘由是这样的,当碰到 foo2()中包含return语句的代码行(代码行上没有其余任何代码),分号会当即自动插入到返回语句以后。请仔细留意上面两个函数中return的不一样之处,foo2函数的return是单独一行的。也不会抛出错误,由于代码的其他部分是彻底有效的,即便它没有获得调用或作任何事情(至关于它就是是一个未使用的代码块,定义了等同于字符串"hello"的属性 bar)。因此,在使用return语句的时候,要留意javascript的这个特色,尽量不要将return关键字写在独立的一行,避免没必要形成没必要要的错误。 在《JavaScript语言精粹》这本书里,这个“自动插入分号”机制被划入到了JavaScript的毒瘤里面,与之并列的前面的全局变量。

6、NaN是什么?如何测试一个值是否等于NaN

NaN属性表明一个“不是数字”的值。这个特殊的值是由于运算不能执行而致使的,不能执行的缘由要么是由于其中的运算对象之一非数字。例如:"abc" / 4,要么是由于运算的结果非数字。例如:除数为零。虽然NaN 意味着“不是数字”,可是它的类型,无论你信不信,是Number

console.log(typeof NaN === "number") // true 

此外, NaN 和任何东西比较,甚至是它本身自己,结果是false:

console.log(NaN == NaN)   // false 

一种半可靠的方法来测试一个数字是否等于NaN,是使用内置函数 isNaN(),但即便使用isNaN() 依然并不是是一个完美的解决方案。 一个更好的解决办法是使用value !== value,若是值等于NaN,只会产生true。由于只有NaN 这货,才会本身不等于本身。 另外,ES6提供了一个新的Number.isNaN() 函数,这是一个不一样的函数,而且比老的全局isNaN()函数更可靠。

7、如下代码的运行结果是什么?

1.console.log(1 + "2" + "2"); // "122";

2.console.log(1 + +"2" + "2"); // "32";

根据运算的顺序,要执行的第一个运算是+"2"(第一个"2"前面的额外 +被视为一元运算符),所以,JavaScript"2" 的类型转换为数字,而后应用一元 + 号(即将其视为一个正数)。其结果就是获得一个数字2

3.console.log(1 + -"1" + "2"); // "02";

4.console.log(+"1" + "1" + "2"); // "112";

5.console.log("a" - "b" + "2"); // "NaN2";

6.console.log("a" - "b" + 2); // NaN;

8、关于逻辑运算符,下面代码的运行结果是什么?

console.log( 0 || 1);   // 1;
console.log( 1 || 2);   // 1;
console.log( 0 && 1);   // 0;
console.log( 1 && 2);   // 2;

JavaScript中, ||&& 都是逻辑运算符,用于在从左至右计算时,返回第一个可彻底肯定的“逻辑值”。

9、如下代码输出的结果是什么?为何?

var a = {},
    b = {key:"b"}, c = {key:"c"}; a[b] = 123; a[c] = 456; console.log(a[b]); 

JavaScript在设置对象的属性的时候,会暗中字符串化参数值;在以上代码中bc都是对象,把它们设置为对象a的参数,它们都将被转换为"[object Object]", 因此a[b]a[c]都至关于a['object Object'];因此a[c]会将a[b]的值覆盖掉,所以,设置或引用a[c]和设置或引用a[b] 彻底相同。因此获得的答案是 456

10、说明如下代码的异同?

line-height:15px;
line-height:150%;
line-height:1.5;
line-height:1.5em;

行高为150%时,会根据父元素的字体大小先计算出行高值而后再让子元素继承。因此当line-height:150%时,子元素的行高等于父元素的fontSize值 * 150%;

当line-height:1.5em时,会根据父元素的字体大小先计算出行高值而后再让子元素继承。因此当line-height:1.5em时,子元素的行高等于父元素的fontSize值 * 1.5em;

当line-height:1.5时,会根据子元素的字体大小动态计算出行高值让子元素继承。因此,当line-height:1.5时,子元素行高等于子元素的fontSize值 * 1.5 = 45px;若是没有子元素,则以自身的fontSize值为准

 

11、关于this指向,如下代码将输出什么?

var person = {
    _name: 'I am John', sayHello: function (){ return this._name; } }; var sayHello = person.sayHello; console.log(sayHello()); console.log(person.sayHello()); 

代码运行的结果是:

undefined
I am John

在执行sayHello()的时候,当访问到this._name时,此时的this已经再也不是person 对象,而是全局窗口对象,也就是widnow对象。与此同时,widnow对象并不存在_name属性,因此返回的是undefined

相关文章
相关标签/搜索