大前端第二阶段(JavaScript)面试题(1-4章)
第一章 JavaScript初识
1、什么是JavaScript?
JavaScript是一种具有面向对象能力的、解释型的弱类型程序设计语言,是基于对象和事件驱动并且具有相对安全性的、可跨平台的客户端脚本语言。(不需要在一个语言环境下运行,而只需要支持它的浏览器即可,浏览器可以直接解析js代码。)
2、JavaScript与ECMAScript的关系?
JavaScript是ECMAScript的语法体现,ECMAScript是JavaScript的语法标准。
3、变量的命名规则?
- 只能以数字、字母、下划线、$组成。
- 不能以数字开头。
- 不能使用保留字、关键字。
- 具有语义化,见名知义。
- 采用驼峰命名法。
4、window.onload的作用?
在文档和页面资源都加载之后执行,避免了加载未完成而无法获取对象的情况。
第二章 JavaScript数据类型
1、js数据类型?
简单数据类型:Number、String、Null、undefined、Boolean
复杂数据类型:Object、Array、Function
2、null和undefined的区别?
null代表“空值”,占据内存空间,代表一个空指针对象,使用typeof得到“Object”。
undefined表示变量没有初始化,不占内存空间,是ECMA第三版引入的,为了区分空指针对象和未初始化的变量,是一个预定义的全局变量。没有返回值的函数和没有实参的形参都是undefined。
3、运算符的种类?
- 算数运算符:+ - * / % ++ –
- 赋值运算符:= += -= *= /=
- 比较运算符:> < >= <= == !== != ===
- 逻辑运算符:&& || !
- 三目运算符:条件 ? 条件成立的代码 : 条件不成立的代码
4、var a = 10;var b = a++;a、b最后的结果是?
a:11、b:10
5、‘==’ 与 ‘ ===’的区别?
==只需要值相等即可,===代表全等,需要值和数据类型都相同。
6、console.log(0.1+0.2==0.3)。
false,小数之间的运算会发生精度缺失,不等于0.3。
7、NaN会在什么样的情况下出现呢?列举出现这种情况的代码。
- 算数运算不能得到正常的数字,比如非数字字符串与数字进行算数运算,‘ ’、null为分母进行算数运算。
- Number进行强制类型转换时,除纯数字字符串、空字符串(null结果为0)、Boolean类型之外,其他的都是NaN,比如非纯数字字符串、undefined。
- parseInt和parseFloat进行强制类型转换时,不能得到正常数字类型的值都是NaN。
- undefined与任何值进行算数运算的值都是NaN。
8、列举三种强制类型转换和两种隐式转换。
强制类型转换
- Number()
- pasreInt()
- parseFloat()
- isNaN()(is not a number)
- 变量.toString()(不能对undefined和null进行转换) / String()(能转任何数据类型)
- Boolean()(undefined、null、false、空字符串、0、NaN为false,其他均为true)
隐式转换
“+”进行运算时,只要两边有一边是字符串,“+”就当作字符串连接符,这时候会将两边的数据都调用String()转成字符串进行拼接。两边都是数字或Boolean、null时,才是算数运算符,这时将调用Number()方法将两边的数据转成Number类型进行运算。
当关系运算符两边有一边是字符串时,会将其他数据类型使用Number()转换,然后比较。
当关系运算符两边都是字符串时,会同时转成Number然后比较关系,但是此时并不是按照Number()的形式转成数字,而是按照字符串对应的ASCII编码,比较ASCII的大小,并且是从左往右依次比较,如果不相等直接得出结果,如果相等则继续比较第二个字符。
复杂数据类型在隐式转换时会先转成String,然后再转成Number运算。
空数组的toString()方法会得到空字符串,而空对象的toString()方法会得到字符串‘[object Object]’。
第三章 流程控制语句
1、document.write()与innerHTML的区别?
两者都能向网页中写入内容。document.write()是直接写入到页面的内容流,如果在写之前没有调用document.open,浏览器会自动调用open,每次写完关闭后重新调用该函数,会导致重写整个网页,将页面上的所有内容清除。而innerHTML只是网页DOM元素的一个属性,表示该元素的html内容,是重写所属元素的内容。innerHTML比document.write()更加灵活,允许更精确的控制页面要刷新的部分。
2、break与continue的区别,举例说明并解释原因?
break与continue都是在循环中终止循环的操作,break是结束循环,后面的循环都不再执行,continue是结束本次循环,即本次循环中continue后面的代码都不再执行,直到执行下一次循环。
for(var i=0;i<=10;i++){
if(i==6){
break;
}
console.log(i);
}
//输出0,1,2,3,4,5就停止,后面的循环停止。
for(var i=0;i<=10;i++){
if(i==6){
continue;
}
console.log(i);
}
//输出0,1,2,3,4,5,7,8,9,10 只跳过6这次循环,不影响后面的循环。
3、使用for循环打印由星号组成的菱形?
var length = 11;//只能是奇数
for (var i = 1; i <= length; i++) {
if (i <= (length + 1) / 2) {//上半部分
for (var j = 1; j <= length; j++) {
if (j > ((length + 1) / 2 - i) && j < ((length + 1) / 2 + i)) {
document.write('*');
} else {
document.write('-');
}
}
} else {//下半部分
for (var j = 1; j <= length; j++) {
if (j > i - ((length + 1) / 2) && j <= length - (i - ((length + 1) / 2))) {
document.write('*');
} else {
document.write('-');
}
}
}
document.write('<br>');
}
第四章 this详解及函数初识
1、this对象的理解?
-
在方法中,this表示该方法所属的对象本身。(对象中的函数称为方法)
var obj = { name:'张三', fn:function(){ console.log(this); } } obj.fn(); //结果是:{name:'张三',fn:function()},说明这里的this是obj对象本身。
-
如果单独使用,this表示全局对象。
console.log(this); //结果是:Window
-
在函数中,this表示全局对象。
function myFunction() { return this; } console.log(myFunction()); //结果是:Window
-
在函数中,在严格模式下,this是未定义的(undefined)。
"use strict"; function myFunction() { return this; } //结果是:undefined
补充:严格模式
定义:严格模式是指在严格的条件下运行js代码,在ECMAScript5引入,通过在脚本或函数的头部添加“use strict”来声明。
好处:
- 消除语法的不合理、不严谨之处,保证代码的运行安全。
- 提高编译器效率,增加运行速度。
- 为未来新版本的js做铺垫。
限制:
- 不允许使用未声明的变量。
- 不允许对变量或函数使用delete操作符。
- 不允许重命名变量。
- 不允许使用八进制。
- 抛弃with语句。
- 不可对只读对象赋值,不可对不可配置对象使用delete操作符。
- 禁止this关键字指向全局对象。
- 不可再if内部声明函数。
- 不允许使用转义字符。
- 不允许对一个使用getter方法读取的属性进行赋值。
- 不允许删除一个不允许删除的属性。
- 变量不能使用“eval、arguments”字符串。
- 在作用域eval()创建的变量不能被调用。
-
在事件中,this指向了接收事件的HTML元素,即触发事件的对象。
-
在call()、apply()、bind()三个函数对象的方法中,允许切换函数执行的上下文环境,即this绑定的对象,所以他们可以将this指向任何地方。
var name = '张三', age = 17; var obj = { name: '李四', objAge: this.age, objFun: function (fm, t) { console.log(this.name + '年龄' + this.age, '来自' + fm + "去往" + t); } } var db = { name: '王五', age: 99 } obj.objFun.call(db, '成都', '上海'); obj.objFun.apply(db, ['成都', '上海']); obj.objFun.bind(db, '成都', '上海')(); obj.objFun.bind(db, ['成都', '上海'])(); // 王五年龄99 来自成都去往上海 // 王五年龄99 来自成都去往上海 // 王五年龄99 来自成都去往上海 // 王五年龄99 来自成都, 上海去往undefined /*从上面四个结果不难看出: bind 返回的是一个新的函数,方法后面多了个 () ,必须调用它才会被执行。 call 、bind 、 apply 这三个函数的第一个参数都是 this 的指向对象,第二个参数差别就来了: call 的参数是直接放进去的,第二第三第 n 个参数全都用逗号分隔,直接放到后面 obj.myFun.call(db,'成都', ... ,'string' )。 apply 的所有参数都必须放在一个数组里面传进去 obj.myFun.apply(db,['成都', ..., 'string' ])。 bind 除了返回是函数以外,它的参数和 call 一样。 当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!*/
2、声明函数的方式有哪些?分别例举。
-
function直接声明
function fn(){ ...; };
-
表达式声明/匿名函数赋值给变量
var fn = function(){ ...; };
-
有名函数赋值给变量
var fn = function fun(){ ...; };
-
Function构造器构造函数(不推荐)
var fn = new Function('a','b',"alert(a+b)"); fn(a,b);
Function
构造函数创建一个新的Function
对象。直接调用此构造函数可用动态创建函数,但会遇到和eval
类似的的安全问题和(相对较小的)性能问题。然而,与eval
不同的是,Function
创建的函数只能在全局作用域中运行。 -
匿名函数
;(function(){console.log(1);})() //匿名函数直接使用会报错,因为js规定函数声明function后面必需有函数名或者匿名函数使用表达式赋给变量。 //解决方法是将匿名函数变成为自执行函数,将其用括号括起来,后面加()代表函数调用,其前面加上;或~防止被前面没加;的代码影响。
3、使用函数计算50、100、150、200、1000以内得所有奇数的和。
function sumOdd(len){
var sum = 0;
for(var i = 1;i<=len;i++){
if(i % 2 == 1){
sum += i;
}
}
return sum;
};
console.log(sumOdd(50));//625
console.log(sumOdd(100));//2500
console.log(sumOdd(150));//5625
console.log(sumOdd(200));//10000
console.log(sumOdd(1000));//250000
说明:隐式转换参考(及图片)自:传智播客官方博客 文章:https://blog.csdn.net/itcast_cn/article/details/82887895,感谢。