一 选择题
1.需要在 html 页面上引用脚本文件myJs.js,下列语句中,正确的是(D)
A <script href="myJs.js" type="text/javascript" />
B <script src="myJs.js" type="text/javascript" />
C <script href="myJs.js" type="text/javascript"></script>
D <script src="myJs.js" type="text/javascript"></script>
需要闭合,链接为 src,选D
2.var arr = [];typeof arr的结果是(C)
- Array
- Function
- Object
- Undefined
我错选为A,解析:[],{}和 null 的 typeof 都是object。
3.请选择结果为真的选项( A )
A null == undefined
B null === undefined
C undefined == false
D NaN == NaN
undefined:未定义的值,希望变量是最原始的状态,而非人为操作的结果,
null:空值,希望表示一个对象被人为的重置为空对象,而非一个变量最原始的状态,
相同点是:都表示一个无效的值,内容具有相似性。null == undefined // true,但是===会返回false,因为全等操作在比较相等性时,不会主动转换分项的数据类型,二者又不属于同一种类型。不要显式的赋值为 undefined,当需要释放一个对象时直接赋值为 null 即可。
NaN 在比较时不相等
4.var a = 4; a.name =‘number’;console.log(a.name)的结果是什么(A)
- undefined
- ‘number’
- 报错
- 4
原始值(Number、String、Boolean、Undefined、Null,Symbol(es6))类型不能有属性,不会报错,会显示 undefined,只有引用值(数组(Array)、对象(Object)、函数(Function))可以动态添加后面可以使用的属性
5.如何遍历下面的 my_data 对象?var my_data={a:’Ape’,b:’Banana’, c:’Citronella’}; (A)
A for(var key in my_data){}
B foreach(my_data as key =>value)
C for(var i=0;i<my_data.length;i++)
D 全不正确
A for in循环:
for (var a in data) {
console.log(a); /*属性名*/
console.log(data[a]); /*属性值*/
};
B PHP 4以上的版本包括了 foreach 结构,这只是一种遍历数组简便方法。foreach 仅能用于数组,当试图将其用于其它数据类型或者一个未初始化的变量时会产生错误。
6.js数组的方法中,哪些方法不能改变自身数组?(B)
A splice
B concat
C sort
D pop
A splice()方法可对数组中已经存在元素进行删除,也可以添加元素到数组中
B contact()用于连接两个或多个数组,不会改变自身数组,仅仅返回被连接数组的一个副本,返回一个新数组。通过所有的 arrayObject 中生成,如果要进行 contact()操作的参数是数组,那么添加的是数组中的元素,不是数组。
C sort()对数组这个所有元素进行排序,如果没有提供比较函数的 compareFunction,按照字符串的 Unicode 码的顺序进行排序。
D pop()用于删除数组中的最后一个元素,并返回被删除的最后一个元素。
7.下面代码的输出结果是多少 (D)
var a = 1;
var b = a;
a = 3;
var arr = [1,2,3];
var newArr = arr;
arr.push(4);
console.log(b,newArr);A. 1,[1,2,3]
B. 3,[1,2,3,4]
C. 3,[1,2,3]
D. 1,[1,2,3,4]
b开始被赋值为 a 的值 1,a值变后不会影响b,数组有时效性,push又增加了一个值 4.
8.以下代码段运行结果是什么?(D)
(function(){
var a= b =1;
})();
console.log(a);
console.log(b);
A 1,1
B error, error
C 1, error
D error,1
var a= b =1; 等价于 b=1; var a=b; b成为全局变量1,所以 a会出现 Uncaught ReferenceError: a is not defined,单独测试 b 时会显示 1,选择 D
9.下面代码的输出结果是多少?(C)
var a = 1;
function foo(n){
return n+1;
}
var b = foo(a);
function foo(n){
a = n + 1;
return n+10;
}
var c = foo(a);
console.log(a,b,c);
A.1,2,11
B.2,2,11
C.3,11,12
D.3,11,11
两个函数名称相同,所以下面的函数会覆盖上面函数,并且声明提升,所以 var b = foo(a); a=1, n=1, 经过函数,a=1+1=2, b=10+1=11, var c = foo(a); n=2, a=2+1=3, c=2+10=12;
10.下列代码输出结果是(A)
var user = {
count : 1,
getCount: function(){
return this.count;
}
}
var count = 2;
var func = user.getCount;
console.log(func());
A 2
B 1
C 报错
D undefined
对象中的属性的值如果不是原始类型(是对象),存储的是指向这个对象的指针(内存地址), var func 被赋值后,拷贝的是 同名方法的内存地址, 打印 result 2 时 getCount 被调用,调用者是全局,浏览器环境就是 window.getCount()
二 简答题
1. 简述call,apply,bind的异同(5分)
Call,apply,bind的作用都是改变this的指向
Call的参数是一个一个传递的
Apply传递的是一个数组
bind 会将改变this后的函数传递回来,不立即执行,在执行的时候传递参数
2.(预编译)(一2分)下列程序中alert按顺序分别输出:( function e(){} )(2 )(100)(10)(100)(123)
var a = 10;
function test(e) {
console.log(e);
function e(){};
arguments[0] = 2;
console.log(e);
a = 100;
f = 123;
console.log(a);
console.log(this.a);
var a;
console.log(a);
}
test(1);
console.log(f);
函数提升会优先于变量提升,函数提升覆盖了变量,所以第一个值是function e(){};第二个值是arguments[0]=2,所以e是 2;第三个值:直接调用函数中a 的值,a=100;第四个值:this指向全局变量,this.a 为10;第五个值:在函数内部重新定义了a,声明提升,a被赋值为100;第六个值:调用 test函数后,f 为123
3.(原型)
function Person(){
count = 0;
}
Person.prototype.name = 'js';
var person1 = new Person();
Person.prototype = {
count:3,
name:'abc'
}
console.log(person1.name);
console.log(new Person().count);
(1) 上述的输出结果是什么
js 3
给对象实例添加一个属性,这个属性就会屏蔽原型对象上的同名属性,不会修改,但会屏蔽访问,重写了 Person 的原型,person1在创建的时候,原型指向已经确定了。
(2) Person.prototype.属性 = ‘属性值’ 和 Person.prototype = {属性名:属性值} 两者的区别是什么?怎样解决这两者所带来的差异?
第一种方法相当于在原型上添加了一共自定义的方法,实例函数可以调用自定义的这个方法。第二种方法相当于重写了默认的prototype。改变了constructor的指向。解决方法就是在字面量定义的prototype里面加上constructor:Person(构造函数名)
4.(this和闭包)
function Person (name) {
this.name = name;
var count = 0;
this.foo1 = function () {
count++;
console.log(count);
console.log(this.name);
}
this.foo2 = function () {
return function () {
console.log(this.name);
}
}
}
var name = 'window';
var count = 3;
var obj = {name:'obj'};
var person1 = new Person('person1');
person1.foo1();
person1.foo2()(); //第二个括号指的是执行他返回的函数
(1) 上述代码的输出结果是多少?(一个4分)
1, person1, window
(2) 将person1.foo1()这句代码改写,使之输出的结果为‘obj’。(4分)
person1.foo1.call(obj)
三 编程题
1. 请自定义一个函数,实现字符串的反转。用JavaScript语言
(1) split(" ") 根据空字符串拆分数组,reverse():数组反转元素位置,join(" "):数组转回字符串,且不带分隔符
function reverseStr(str){
return str.split("").reverse().join("");
}
(2) 用递减的 for 循环反转字符串
function reverseString(str) {
var newString = "";
for (var i = str.length - 1; i >= 0; i--) {
newString += str[i];
}
return newString;
}
reverseString('hello');
(3)用递归反转字符串,使用 String.prototype.substr() 方法(返回一个字符串中从指定位置开始到指定字符数的字符)和 String.prototype.charAt() 方法(从一个字符串中返回指定的字符)、
2. 已知数组arr = [1,2,5,40,7,8,12,50];执行arr.sort()的结果是什么,与预期的结果相符吗?如果不符,请改进执行的这行代码。
结果:[1, 12, 2, 40, 5, 50, 7, 8]
改进: arr.sort(function(a,b){return a-b;})
出现问题的原因是:元素转换为字符串,用字符串的首字母进行比较,如果第一个字符相同,则会继续比较第二个字符,改进的方法是:按照冒泡排序的方法,相减之后排序。
3. 已知arr = [1, 2, 3, 4, 1, 1, 1, 3, 4, 5, 6],使用数组方法(filter()或其他方法)来实现数组的去重。用JavaScript写出完整代码。
(1)arr2 = arr.filter(function(item, index,arr) {
return arr.indexOf(item)===index;
});
let arr = [1,2,1,'j',5,'1',true,2,5,'h',true];
function duplicateRemoval(arr) {
let newArr = []; //定义接收去重后结果的新数组
for(let i = 0;i<arr.length;i++){
//判断新数组中是否存在当前索引为i的原数组元素
if (newArr.indexOf(arr[i])===-1) {
//如果不存在,则将其放到新数组的最后位置
newArr.push(arr[i]);
}
}
return newArr;//返回去重后的新数组
}
console.log(duplicateRemoval(arr));
(2)两层 for 循环:
//定义一个有重复数据的数组
let arr = [1,2,1,'j',5,'1',true,2,5,'h',true];
function duplicateRemoval(arr) {
for(let i = 0;i<arr.length;i++){
for (let j = i+1; j < arr.length; j++) {
if (arr[i]===arr[j]) {
arr.splice(j,1);//删除满足条件的元素
j--; //因为当前索引值的元素被删除,且后面元素往前移
}
}
}
}
duplicateRemoval(arr); //方法调用
console.log(arr);