JS题目及答案整理

原文链接在这里,大部分答案是按照自己的理解修改的,也请大家理解为主。

JavaScript

介绍js的基本数据类型

Undefined、Null、Boolean、Number、String、
ECMAScript 2015 新增:Symbol(创建后独一无二且不可变的数据类型 )

介绍js有哪些内置对象?

构造器对象:Object、Array、Boolean、Number、String、Function、RegExp、Date、Error
普通对象:Math、JSON

Object 是 JavaScript 中所有对象的父对象

参考:http://www.ibm.com/developerw...

说几条写JavaScript的基本规范?

1.不要在同一行声明多个变量。
2.请使用 ===/!==来比较true/false或者数值
3.使用对象字面量替代new Array这种形式
4.不要使用全局函数。
5.Switch语句必须带有default分支
6.函数不应该有时候有返回值,有时候没有返回值。
7.For循环必须使用大括号
8.If语句必须使用大括号
9.for-in循环中的变量 应该使用var关键字明确限定作用域,从而避免作用域污染。

JavaScript原型,原型链 ? 有什么特点?

每个对象都会在其内部初始化一个原型属性,这个原型指向的是一个对象,这个对象同样有一个原型属性,这样一层一层向上,直到Object对象。当我们访问一个对象的属性时,如果当前对象内部不存在这个属性,那么就会去它的原型上去找这个属性,它的原型又会有自己的原型属性,这样沿着找下去,就是我们平时所说的原型链的概念。

关系:instance.constructor.prototype = instance.__proto__

特点:
JavaScript对象是通过引用来传递的,我们创建的每个实例对象中并没有一份属于自己的原型副本。
所以当我们修改原型时,与之相关的对象也会继承这一改变。
当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的话,
就会查找他的Prototype对象是否有这个属性,如此递推下去,一直检索到 Object 对象。
function Func(){}
Func.prototype.name = "Sean";
Func.prototype.getInfo = function() {
    return this.name;
}
var person = new Func();//现在可以参考var person = Object.create(oldObject);
console.log(person.getInfo()); //person拥有了Func的属性和方法
//"Sean"
console.log(Func.prototype);
// Func { name="Sean", getInfo=function()}

JavaScript有几种类型的值?你能画一下他们的内存图吗?

栈:原始数据类型(Undefined,Null,Boolean,Number,String)
堆:引用数据类型(对象、数组和函数)

两种类型的区别是:存储位置不同。
原始数据类型是直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;
引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,
取得地址后从堆中获得实体。

JS题目及答案整理_第1张图片

如何将字符串转化为数字,例如'12.3b'?

1.转换函数 parseInt(str),parseFloat(str);
1.1 parseFloat('12.3'); //12.3
1.2 parseFloat('12.3b'); //12.3

2.强制类型转换 Number(str)
2.1 Number('12.3') //12.3
2.2  Number('12.3b') //NaN

3.JS方法 var num = str - 0;
3.1 var num = '12.3' - 0; //12.3 
3.2 var num = '12.3b' - 0; //NaN

4.正则表达式,'12.3b'.match(/(\d)+(\.)?(\d)+/g)[0] * 1, 但是这个不太靠谱,提供一种思路而已。

如何实现千位分隔符:将浮点数点左边的数每三位添加一个逗号,如12000000.11转化为『12,000,000.11』?

function commafy(num){
    return num && num.toString()
        .replace(/(\d)(?=(\d{3})+\.)/g, function(match, p1){ // !replace函数:把正则匹配到的值用函数的返回值来替换
            return match + ',';
        });
}

这个正则的原理是:匹配 【后面紧跟着3位数字的倍数加一个小数点】 的数字,要注意 【后面紧跟着的三位数字加一个小数点】 不会被匹配进去哦,也就是(?=x)里面的x不会被匹配进去。其实共匹配了两次,第一次匹配到的子字符串是"2",因后面紧跟着"345678.",第二次匹配到的是"5",因后面紧跟着"678."。而且其实函数改为return p1 + ',' 也可以达到同样的替换效果。

如何实现数组的随机排序?

方法一:
var arr = [1,2,3,4,5,6,7,8,9,10];
function randSort1(arr){
    for(var i = 0,len = arr.length;i < len; i++ ){
        var rand = parseInt(Math.random()*len);
        var temp = arr[rand];
        arr[rand] = arr[i];
        arr[i] = temp;
    }
    return arr;
}
console.log(randSort1(arr));
方法二:
var arr = [1,2,3,4,5,6,7,8,9,10];
function randSort2(arr){
    var mixedArray = [];
    while(arr.length > 0){
        var randomIndex = parseInt(Math.random()*arr.length);
        mixedArray.push(arr[randomIndex]);
        arr.splice(randomIndex, 1);
    }
    return mixedArray;
}
console.log(randSort2(arr));
方法三:
var arr = [1,2,3,4,5,6,7,8,9,10];
arr.sort(function(){
    return Math.random() - 0.5;
})
console.log(arr);

Javascript如何实现继承?

1、原型链
2、借用构造函数
3、组合继承(原型链+借用构造函数)
4、原型式继承
5、寄生式继承
6、寄生组合式继承

1.原型链

原理:把父类的一个实例赋给子类的prototype属性。

function Super() {
  this.superProperty = 'super';
  this.arr = [1];
}

Super.prototype.getSuperValue = function() {
  return this.superProperty;
}

function Sub() {
  this.subProperty = 'sub';
} 

//注意,下面一行就是继承了,将Super的一个实例赋值给Sub.prototype
Sub.prototype = new Super();

Sub.prototype.getSubValue = function() {
  return this.subProperty;
}

var obj = new Sub();
obj.getSubValue(); //'sub'
obj.getSuperValue(); //'super' 可以调用继承自Super对象的方法

//Sub的不同实例共享Super对象的属性
var obj2 = new Sub();
obj.arr.push(2);
obj.arr; //[1,2]
obj2.arr; //[1,2]

优点:简单。
缺点:
子类之间会共享继承来的属性和方法,其中,共享引用类型属性是我们不希望看到的(在这里是arr);
创建子类时,无法向父类构造函数传参。

原型继承原型图:

JS题目及答案整理_第2张图片

2.借用构造函数

原理:在子类构造函数内部调用超类构造函数。即用call或apply方法给子类构造函数中的this调用父类构造函数,使子类构造函数构造出来实例对象拥有父类拥有的属性,从而实现继承。

function Super() {
  this.arr = [1,2,3];
  this.getArr() {
    return this.arr;
  }
}
function Sub() {
  Super.call(this);
}

var obj = new Sub();
obj.arr.push(4);
obj.arr; //[1,2,3,4]
var obj2 = new Sub();
obj2.arr;// [1,2,3] 不共享引用类型属性!

可以向父类构造函数传递参数:
function Super(name) {
  this.name = name;
}
function Sub(name) {
  Super.call(this, name);
}

var obj = new Sub("Darcy");
obj.name; // Darcy

优缺点:
优点:实例间不会共享引用类型属性;可以向超类传递参数。
缺点:无法实现函数复用,即,相同的函数在每个实例中都有一份,影响性能,消耗内存。(在这里为getArr()

3.组合继承(常用)

原理:原型链 + 借用构造函数。
既用原型链实现了对原型属性和方法的继承(需要共享的),也通过构造函数实现了对实例属性的继承(不需要共享的)。既实现了函数复用,也使得每个实例都有自己的属性。

function Super(name) {
  this.name = name;
  this.arr = [1,2,3];
}
Super.prototype.getName = function() {
  return this.name;
}

function Sub(name, age) {
  Super.call(this, name);
  this.age = age;
}
Sub.prototype = new Super();
//给Sub.prototype赋值为Super的实例对象
//上面这句其实是给Sub.prototype重新赋值,
//使得Sub.prototype这个对象自己没有了constructor属性,
//这时如果去找Sub.prototype.constructor,
//会沿着原型链继续向上找到Super(name),
//所以我们需要让Sub的构造函数重新指回Sub
Sub.prototype.constructor = Sub; 
Sub.prototype.getAge = function() {
  return this.age;
}

var obj1 = new Sub("Darcy", 18);
obj1.arr.push(4);
obj1.arr; //[1,2,3,4]

delete obj1.arr; 
//这时如果删除obj1通过调用Super的构造函数自身拥有的实例属性arr,
//再读取arr时,就会沿着原型链向上查找,
//找到通过Sub.prototype = new Super()得到的arr属性
obj1.arr; // [1,2,3]

obj1.getName(); //"Darcy"
obj1.getAge(); //18
var obj2 = new Sub("Iris", 17);
obj2.arr; // [1,2,3]
obj2.getName(); //"Iris"
obj2.getAge(); // 17

优点:
1.通过借用构造函数,使得继承的父类的引用类型属性不再共享
2.通过借用构造函数,使得可以在创建子类时,向父类构造函数传参
3.通过原型继承,使得可以共享继承来的函数,而不需要每个实例中都保存一份。

缺点:原型继承和借用构造函数分别调用了一次父类的构造函数,一共调用了两次父类的构造函数

4.原型式继承

原理:借助原型,基于已有对象创建新对象。把父类的原型复制一份,赋给子类的原型。

//核心代码:
function object(o) {
  function F() {};
  F.prototype = o;
  return new F();
}

//其实就是ES5中的Object.create(superObj, argsObj) 返回一个实例对象

var person = {
    name: "Darcy",
    friends: ["Iris", "Nichol"]
}

var anotherPerson = Object.create(person, {name: {value: "Stella"}});
anotherPerson; //{name: "Stella"}

优点:
如果想让一个对象与另一个对象保持类似,原型式继承是很贴切的。
缺点:
与原型链一样,共享继承来的引用类型的属性的值是我们不希望的。

5.寄生式继承

原理:寄生式继承是与原型式继承紧密相关的一种思路,即创建一个仅用于封装继承过程的函数,函数内部以某种方式来增强对象,最后再像真的做了所有工作一样返回对象。

具体实现:定义一个子类构造函数,内部新建一个临时对象,通过Object.create(original)使用原型式继承继承父类对象,然后加上子类对象自己的其他属性,最后返回这个临时对象。

//核心代码
function createAnother(original) { 
    var clone = Object.create(original); //此处用到了原型式继承,返回的是一个实例对象
    clone.sayHi = function() {
        c("Hi");
    };
    return clone;
}

var person = {                             //父类实例
    name: "Nicholas",
    friends: ["Shelby","Court","Van"]
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();

寄生式继承在主要考虑对象而不是创建自定义类型和构造函数时,是十分有用的。但是如果考虑到用寄生式继承为对象添加函数等,由于没有用到原型,做不到函数复用,会导致效率降低。

6.寄生组合式继承

原理:这个名字并不是很贴切,虽然叫寄生组合式继承,但是和寄生式继承关系不是很大,主要是用原型式继承来实现原型属性的继承,用借用构造函数模式继承实例属性。寄生组合式继承和组合继承的区别在于:

1.在继承原型属性时,组合继承用原型链继承了整个父类(通过将父类实例赋值给子类构造函数的原型对象来实现),这使子类的原型上有了一份父类的实例属性,而我们其实已经通过借用构造函数在子类实例上生成了父类的实例属性,所以多了一份实例属性。而寄生组合式继承没有用sub.prototype = new Array(),是用原型式继承Object.create(super.prototype)做到了只继承父类的原型属性,不继承父类的实例属性。
2.组合继承调用了两次超类型构造函数,寄生组合式继承调用了一次(避免了new Super())。

//核心代码
function inheritProperty(sub, superObj) { 
    sub.prototype = Object.create(superObj.prototype);
    //把super.prototype作为sub.prototype的值,
    //避免了new Super(),就少调用了一次 Super()构造函数
    sub.prototype.constructor = sub; //增强对象
}

function Super(name) {
  this.name = name;
  this.arr = [1,2,3];
}
Super.prototype.getName = function() {
  return this.name;
}

function Sub(name, age) {
  Super.call(this, name);  //借用构造函数
  this.age = age;
}

inheritProperty(Sub, Super); //调用实现寄生组合式继承的函数
Sub.prototype.getAge = function() {
  return this.age;
}

var obj1 = new Sub("Darcy", 18);
obj1.arr.push(4);
obj1.arr; //[1,2,3,4]

delete obj1.arr; 
//这时如果删除obj1通过调用Super的构造函数自身拥有的实例属性arr,
//再读取arr时,就会沿着原型链向上查找,发现找不到了
obj1.arr; // undefined

obj1.getName(); //"Darcy"
obj1.getAge(); //18
var obj2 = new Sub("Iris", 17);
obj2.arr; // [1,2,3]
obj2.getName(); //"Iris"
obj2.getAge(); // 17

寄生组合式继承原型链图:

JS题目及答案整理_第3张图片

优缺点:
这种继承方式理论上是完美的,但是由于出现的较晚,人们大多数使用的是组合继承模式。

参考:js继承文章

javascript创建对象的几种方式?

javascript创建对象简单的说,无非就是使用内置对象或各种自定义对象,当然还可以用JSON; 但写法有很多种,也能混合使用。

1、对象字面量的方式

var person={
  firstname:"Mark",
  lastname:"Yun",
  age:25,
  eyecolor:"black"
};

2、用function来模拟无参的构造函数

function Person(){}
//定义一个function,如果使用new"实例化",该function可以看作是一个Class
var person=new Person();
person.name="Mark";
person.age="25";
person.work=function(){
    alert(person.name+" hello...");
}
person.work();

3、用function来模拟有参构造函数来实现(用this关键字定义构造的上下文属性)

function Pet(name,age,hobby){
   this.name=name;//this作用域:当前对象
   this.age=age;
   this.hobby=hobby;
   this.eat=function(){
      alert("我叫"+this.name+",我喜欢"+this.hobby+",是个程序员");
   }
}
var maidou = new Pet("麦兜",25,"coding");//实例化、创建对象
maidou.eat();//调用eat方法

4、使用Object.create()方法

var Animal = {
    type: "Invertebrates", //"无脊椎动物"
    displayType: function() {
        console.log(this.type);
    }
}

var animal1 = Object.create(Animal);
animal1.displayType(); // Invertebrates

var fish = Object.create(Animal);
fish.type = "Fishes";
fish.displayType(); // Fishes

5、用工厂方式来创建(内置对象)

var wcDog = new Object();
wcDog.name="旺财";
wcDog.age=3;
wcDog.work=function(){
   alert("我是"+wcDog.name+",汪汪汪......");
}
wcDog.work();

6、用原型方式来创建

function Dog(){

}
Dog.prototype.name="旺财";
Dog.prototype.eat=function(){
    alert(this.name+"是个吃货");
}
var wangcai =new Dog();
wangcai.eat();

7、用混合方式来创建(数据类型属性定义在构造函数中,函数类型属性定义在原型上)

function Car(name,price){
    this.name=name;
    this.price=price;
}
Car.prototype.sell=function(){
   alert("我是"+this.name+",我现在卖"+this.price+"万元");
}
var camry =new Car("凯美瑞",27);
camry.sell();

Javascript作用域链?

外层函数无法查看内层函数的内部细节,但内层函数可以查看其外层函数细节,直至全局环境中的细节。
当需要从内层函数查找某一属性或方法时,会现在当前作用域查找,如果没有找到,就会到它的上一层作用域查找,
直至全局环境,这种组织形式就是作用域链。

谈谈This对象的理解。

  • 全局环境中的this,指的是 window

  • 构造函数中的this,指的是实例对象

  • 对象方法中的this,指的是调用这个方法的对象

  • 事件触发中的this,指的是触发这个事件的对象,特殊的是,IE中的attachEvent中的this总是指向全局对象Window

eval是做什么的?

它的功能是把对应的字符串解析成JS代码并运行;
应该避免使用eval,不安全,且非常耗性能(2次,一次解析成js语句,一次执行)。
由JSON字符串转换为JSON对象的时候可以用eval,var obj =eval('('+ str +')');

什么是window对象? 什么是document对象?

window对象是指浏览器打开的窗口。
document对象是对HTML文档对象的一个只读引用,window对象的一个属性。

null,undefined 的区别?

1.
null          用来表示一个【对象】是“没有值”的,也就是值为“空”;
undefined     用来表示一个【变量】声明了没有初始化(赋值);

2.
typeof undefined
//"undefined"
例如变量被声明了,但没有赋值时,Javascript会将其默认值设为undefined

typeof null
//"object"
null : 是一个对象(空对象, 没有任何属性和方法);
常被放在:期望一个对象,但是不引用任何对象的参数位置。也就是说对象的初始化,例如:
var obj = null;
console.log(typeof obj === "object"); // true

3.
在验证null时,一定要使用 `===` ,因为 `==` 无法区分 null 和 undefined
null == undefined // true
null === undefined // false

再来一个例子:

null
Q:有张三这个人么?
A:有!
Q:张三有房子么?
A:没有!

undefined
Q:有张三这个人么?
A:有!
Q: 张三有多少岁?
A: 不知道(没有被告诉)

参考阅读:undefined与null的区别

写一个通用的事件侦听器函数。

// event(事件)工具集,来源:github.com/markyun
markyun.Event = {
    // 页面加载完成后
    readyEvent : function(fn) {
        if (fn==null) {
            fn=document;
        }
        var oldonload = window.onload;
        if (typeof window.onload != 'function') {
            window.onload = fn;
        } else {
            window.onload = function() {
                oldonload();
                fn();
            };
        }
    },
    // 视能力分别使用dom0||dom2||IE方式 来绑定事件
    // 参数: 操作的元素,事件名称 ,事件处理程序
    addEvent : function(element, type, handler) {
        if (element.addEventListener) {
            //事件类型、需要执行的函数、是否捕捉
            element.addEventListener(type, handler, false);
        } else if (element.attachEvent) {
            element.attachEvent('on' + type, function() {
                handler.call(element);
            });
        } else {
            element['on' + type] = handler;
        }
    },
    // 移除事件
    removeEvent : function(element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.datachEvent) {
            element.detachEvent('on' + type, handler);
        } else {
            element['on' + type] = null;
        }
    },
    // 阻止事件 (主要是事件冒泡,因为IE不支持事件捕获)
    stopPropagation : function(ev) {
        if (ev.stopPropagation) {
            ev.stopPropagation();
        } else {
            ev.cancelBubble = true;
        }
    },
    // 取消事件的默认行为
    preventDefault : function(event) {
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }
    },
    // 获取事件目标
    getTarget : function(event) {
        return event.target || event.srcElement;
    },
    // 获取event对象的引用,取到事件的所有信息,确保随时能使用event;
    getEvent : function(e) {
        var ev = e || window.event;
        if (!ev) {
            var c = this.getEvent.caller;
            while (c) {
                ev = c.arguments[0];
                if (ev && Event == ev.constructor) {
                    break;
                }
                c = c.caller;
            }
        }
        return ev;
    }
};

["1", "2", "3"].map(parseInt) 答案是多少?

parseInt(val, radix)能解析一个字符串,返回一个整数,radix表示要解析的数字的基数,该值可选,不传默认为10。
【radix介于 2 ~ 36 之间,并且字符串中的数字不能大于radix才能正确返回数字结果值。如果值为0或空,则为默认值10。】
但此处 map 传了 3 个参数 (value, index, array),所以parseInt拿到前面两个参数value和index。

重写parseInt函数测试一下:

function parseInt(str, radix) {
    return 'parseInt(' + str + ', ' + radix + ')';
};
var a=["1", "2", "3"];
a.map(parseInt);  // ["parseInt(1, 0)", "parseInt(2, 1)", "parseInt(3, 2)"]

value不能大于radix的原因是:二进制里面,没有数字3,导致出现超范围的radix赋值和不合法的进制解析,才会返回NaN。

所以["1", "2", "3"].map(parseInt) 答案也就是:[1, NaN, NaN]

详细解析:http://blog.csdn.net/justjava...

事件是?IE与火狐的事件机制有什么区别? 如何阻止冒泡?

  1. 事件是我们在网页中的某个操作(有的操作对应多个事件),是可以被 JavaScript 侦测到的行为。例如:当我们点击一个按钮就会产生一个事件。

  2. 事件处理机制:IE只支持事件冒泡,Firefox同时支持事件捕获和事件冒泡两种事件处理模型。

  3. ev.stopPropagation();(旧ie的方法 ev.cancelBubble = true;)。

什么是闭包(closure),为什么要用它?

闭包是由函数和它引用的外部词法环境组合而成的。最常见的方式就是在一个函数内嵌套另一个函数,利用内部函数访问其引用的外部函数的词法环境中的参数和变量,可以将函数内的变量和方法传递到函数外,且不会被垃圾回收机制回收,始终保存在内存中。

闭包的应用:

1.使外部函数的词法环境的变量始终保存在内存中
2.保存变量现场(for循环为li列表绑定事件)
3.封装(共享函数,私有变量)

1.使外部函数的词法环境的变量始终保存在内存中

执行say667()后,say667()闭包内部变量会存在,而闭包内部函数的内部变量不会存在
        使得Javascript的垃圾回收机制GC不会收回say667()所占用的资源
        因为say667()的内部函数的执行需要依赖say667()中的变量
        这是对闭包作用的非常直白的描述

          function say667() {
            // Local variable that ends up within closure
            var num = 666;
            var sayAlert = function() {
                alert(num);
            }
            num++;
            return sayAlert;
        }

         var sayAlert = say667();
         sayAlert()//执行结果应该弹出的667

2.保存变量现场(for循环为li列表绑定事件)

        //li节点的onclick事件都能正确的弹出当前被点击的li索引
         
  • index = 0
  • index = 1
  • index = 2
  • index = 3

javascript 代码中的"use strict";是什么意思 ? 使用它区别是什么?

use strict是一种ECMAscript 5 添加的(严格)运行模式,使得 Javascript 在更严格的条件下运行,消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为,使编码更加规范化。

区别:

  1. 默认支持的糟糕特性都会被禁用,比如不能用with;

  2. 全局变量必须用var关键字显式声明;

  3. 函数必须声明在顶层,不允许声明在非函数代码块内,比如if和for的大括号内;

  4. arguments.callee也不允许使用;

  5. 消除代码运行的一些不安全之处,保证代码运行的安全,限制函数中的arguments修改;

  6. 严格模式下的eval函数的行为和非严格模式的也不相同;

  7. 提高编译器效率,增加运行速度。

如何判断一个对象是否属于某个类?

1.使用instanceof 
if(a instanceof Person){
    alert('yes');
}
2.使用constructor
if(a.constructor === Person){}

new操作符具体干了什么呢?

1、创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
2、属性和方法被加入到 this 引用的对象中。
3、新创建的对象由 this 所引用,并且最后隐式的返回 this 。

var obj  = {};
obj.__proto__ = Base.prototype;
Base.call(obj);

用原生JavaScript的实现过什么功能吗?

Javascript中,有一个函数,执行时对象查找时,永远不会去查找原型,这个函数是?

hasOwnProperty

javaScript中hasOwnProperty函数方法是返回一个布尔值,指出一个对象是否具有指定名称的属性。此方法无法检查该对象的原型链中是否具有该属性;该属性必须是对象本身的一个成员。

使用方法:

obj.hasOwnProperty(proName)

其中参数obj是必选项。一个对象的实例。
proName是必选项。一个属性名称的字符串值。

如果 obj 具有指定名称的属性,那么JavaScript中hasOwnProperty函数方法返回 true,反之则返回 false。

JSON 的了解?

官网地址: http://json.org/json-zh.html

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。
    它是基于JavaScript的一个子集。数据格式简单, 易于读写, 占用带宽小
    如:{"age":"12", "name":"back"}

    JSON字符串转换为JSON对象:
    var obj =eval('('+ str +')');
    var obj = str.parseJSON();
    var obj = JSON.parse(str);

    JSON对象转换为JSON字符串:
    var last=obj.toJSONString();
    var last=JSON.stringify(obj);

解释一下这段代码的意思吗?

[].forEach.call($$("*"),function(a){
    a.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16)
})

给页面上的所有元素添加outline,颜色随机。

js延迟加载/异步加载的方式有哪些?

defer和async
动态创建DOM方式:创建script,插入到DOM中,加载完毕后callBack(用得最多)
按需异步载入js

Ajax 是什么? 如何创建一个Ajax?

    ajax的全称:Asynchronous Javascript And XML。
    异步传输+js+xml。
    所谓异步,在这里简单地解释就是:向服务器发送请求的时候,我们不必等待结果,而是可以同时做其他的事情,等到有了结果它自己会根据设定进行后续操作,与此同时,页面是不会发生整页刷新的,提高了用户体验。

    (1)创建XMLHttpRequest对象,也就是创建一个异步调用对象
    (2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息
    (3)设置响应HTTP请求状态变化的函数
    (4)发送HTTP请求
    (5)获取异步调用返回的数据
    (6)使用JavaScript和DOM实现局部刷新

Ajax 解决浏览器缓存问题?

    1、在ajax发送请求前加上 anyAjaxObj.setRequestHeader("If-Modified-Since","0")。

    2、在ajax发送请求前加上 anyAjaxObj.setRequestHeader("Cache-Control","no-cache")。

    3、在URL后面加上一个随机数: "fresh=" + Math.random();。

    4、在URL后面加上时间搓:"nowtime=" + new Date().getTime();。

    5、如果是使用jQuery,直接这样就可以了 $.ajaxSetup({cache:false})。这样页面的所有ajax都会执行这条语句就是不需要保存缓存记录。

同步和异步的区别?

同步的概念应该是来自于OS中关于同步的概念:不同进程为协同完成某项工作而在先后次序上调整(通过阻塞,唤醒等方式).同步强调的是顺序性.谁先谁后.异步则不存在这种顺序性.

同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作。

异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。

如何解决跨域问题?

CORS,jsonp、 iframe、window.name、window.postMessage、服务器上设置代理页面

CORS:设置 Access-Control-Allow-Origin

JSONP原理:利用script标签可以访问跨域的请求的原理。 首先在网页上添加一个script标签,设置这个script标签的src属性用于向服务器请求JSON数据 ,src属性的查询字符串需要加callback函数,用来指定回调函数的名字 。而这个函数是在资源加载之前就已经在前端定义好的,它接受一个参数并利用这个参数做一些事情。向服务器请求后,服务器会将JSON数据放在指定名字的回调函数里作为其参数传回来。这时,因为函数已经在前端定义好了,所以会直接调用。

  • 页面编码和被请求的资源编码如果不一致如何处理?

模块化开发怎么做?

 [ 立即执行函数](http://benalman.com/news/2010/11/immediately-invoked-function-expression/),不暴露私有成员

        var module1 = (function(){
            var _count = 0;
            var m1 = function(){
              //...
            };
            var m2 = function(){
              //...
            };
            return {
              m1 : m1,
              m2 : m2
            };
          })();

(待完善)
  • AMD(Modules/Asynchronous-Definition)、CMD(Common Module Definition)规范区别?

    > AMD 规范在这里:https://github.com/amdjs/amdjs-api/wiki/AMD
    
    > CMD 规范在这里:https://github.com/seajs/seajs/issues/242
    
        Asynchronous Module Definition,异步模块定义,所有的模块将被异步加载,模块加载不影响后面语句运行。所有依赖某些模块的语句均放置在回调函数中。
    
         区别:
    
    1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.

    2. CMD 推崇依赖就近,AMD 推崇依赖前置。看代码:

          // CMD
          define(function(require, exports, module) {
    3. a = require('./a')

    a.doSomething()
    // 此处略去 100 行
    var b = require('./b') // 依赖可以就近书写
    b.doSomething()
    // ...

        })
    
        // AMD 默认推荐
        define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好

    a.doSomething()
    // 此处略去 100 行
    b.doSomething()
    // ...

        })
    
  • requireJS的核心原理是什么?(如何动态加载的?如何避免多次加载的?如何
    缓存的?)

    参考:http://annn.me/how-to-realize-cmd-loader/
  • JS模块加载器的轮子怎么造,也就是如何实现一个模块加载器?

  • 谈一谈你对ECMAScript6的了解?

  • ECMAScript6 怎么写class么,为什么会出现class这种东西?

documen.write和 innerHTML的区别

    document.write只能重绘整个页面

    innerHTML可以重绘页面的一部分

DOM操作——怎样添加、移除、移动、复制、创建和查找节点?

    (1)创建新节点
      createDocumentFragment()    //创建一个DOM片段
      createElement()   //创建一个具体的元素
      createTextNode()   //创建一个文本节点
    (2)添加、移除、替换、插入
      appendChild()
      removeChild()
      replaceChild()
      insertBefore() //在已有的子节点前插入一个新的子节点
    (3)查找
      getElementsByTagName()    //通过标签名称
      getElementsByName()    //通过元素的Name属性的值(IE容错能力较强,会得到一个数组,其中包括id等于name值的)
      getElementById()    //通过元素Id,唯一性

.call() 和 .apply() 的区别?

.apply()只有两个参数,第一个参数是调用当前函数的对象,第二个参数是一个数组,里面的值是传入当前调用的函数的参数。
.cal()可以有多个参数,第一个参数还是调用当前函数的对象,而要传入当前调用的函数的参数是直接用第2、3、4...个参数传入的。

例子中用 add 来替换 sub,add.call(sub,3,1) == add(3,1) ,所以运行结果为:alert(4);

注意:js 中的函数其实是对象,函数名是对 Function 对象的引用。

function add(a,b){
    alert(a+b);
}
function sub(a,b){
    alert(a-b);
}
add.call(sub,3,1);

数组和对象有哪些原生方法,列举一下?

Object: create, toString,valueOf,hasOwnProperty
Array: isArray, splice,forEach,find,concat,pop,push,reverse,shift,slice
  • JS 怎么实现一个类。怎么实例化这个类

  • JavaScript中的作用域与变量声明提升?

  • 如何编写高性能的Javascript?

  • 那些操作会造成内存泄漏?

  • JQuery的源码看过吗?能不能简单概况一下它的实现原理?

  • jQuery.fn的init方法返回的this指的是什么对象?为什么要返回this?

  • jquery中如何将数组转化为json字符串,然后再转化回来?

  • jQuery 的属性拷贝(extend)的实现原理是什么,如何实现深拷贝?

  • jquery.extend 与 jquery.fn.extend的区别?

    • jquery.extend 为jquery类添加类方法,可以理解为添加静态方法

    • jquery.fn.extend:

      源码中jquery.fn = jquery.prototype,所以对jquery.fn的扩展,就是为jquery类添加成员函数

      使用:

    jquery.extend扩展,需要通过jquery类来调用,而jquery.fn.extend扩展,所有jquery实例都可以直接调用。

  • jQuery 的队列是如何实现的?队列可以用在哪些地方?

  • 谈一下Jquery中的bind(),live(),delegate(),on()的区别?

  • JQuery一个对象可以同时绑定多个事件,这是如何实现的?

  • 是否知道自定义事件。jQuery里的fire函数是什么意思,什么时候用?

  • jQuery 是通过哪个方法和 Sizzle 选择器结合的?(jQuery.fn.find()进入Sizzle)

  • 针对 jQuery性能的优化方法?

  • Jquery与jQuery UI 有啥区别?

    *jQuery是一个js库,主要提供的功能是选择器,属性修改和事件绑定等等。

    *jQuery UI则是在jQuery的基础上,利用jQuery的扩展性,设计的插件。
     提供了一些常用的界面元素,诸如对话框、拖动行为、改变大小行为等等
  • JQuery的源码看过吗?能不能简单说一下它的实现原理?

  • jquery 中如何将数组转化为json字符串,然后再转化回来?

jQuery中没有提供这个功能,所以你需要先编写两个jQuery的扩展:

    $.fn.stringifyArray = function(array) {
        return JSON.stringify(array)
    }

    $.fn.parseArray = function(array) {
        return JSON.parse(array)
    }

    然后调用:
    $("").stringifyArray(array)
  • jQuery和Zepto的区别?各自的使用场景?

  • 针对 jQuery 的优化方法?

        *基于Class的选择性的性能相对于Id选择器开销很大,因为需遍历所有DOM元素。
    
        *频繁操作的DOM,先缓存起来再操作。用Jquery的链式调用更好。

    比如:var str=$("a").attr("href");

        *for (var i = size; i < arr.length; i++) {}

    for 循环每一次循环都查找了数组 (arr) 的.length 属性,在开始循环的时候设置一个变量来存储这个数字,可以让循环跑得更快:
    for (var i = size, length = arr.length; i < length; i++) {}

  • Zepto的点透问题如何解决?

  • jQueryUI如何自定义组件?

  • 需求:实现一个页面操作不会整页刷新的网站,并且能在浏览器前进、后退时正确响应。给出你的技术实现方案?

  • 如何判断当前脚本运行在浏览器还是node环境中?(阿里)

    this === window ? 'browser' : 'node';

    通过判断Global对象是否为window,如果不为window,当前脚本没有运行在浏览器中

  • 移动端最小触控区域是多大?

  • jQuery 的 slideUp动画 ,如果目标元素是被外部事件驱动, 当鼠标快速地连续触发外部元素事件, 动画会滞后的反复执行,该如何处理呢?

    jquery stop(): 如:$("#div").stop().animate({width:"100px"},100);

  • 把 Script 标签 放在页面的最底部的body封闭之前 和封闭之后有什么区别?浏览器会如何解析它们?

  • 移动端的点击事件的有延迟,时间是多久,为什么会有? 怎么解决这个延时?(click 有 300ms 延迟,为了实现safari的双击事件的设计,浏览器要知道你是不是要双击操作。)

  • 知道各种JS框架(Angular, Backbone, Ember, React, Meteor, Knockout...)么? 能讲出他们各自的优点和缺点么?

  • Underscore 对哪些 JS 原生对象进行了扩展以及提供了哪些好用的函数方法?

  • 解释JavaScript中的作用域与变量声明提升?

  • 那些操作会造成内存泄漏?

    内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
    垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。

    setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
    闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)

  • JQuery一个对象可以同时绑定多个事件,这是如何实现的?

    • 多个事件同一个函数:

      $("div").on("click mouseover", function(){});
    • 多个事件不同函数

      $("div").on({
          click: function(){},
          mouseover: function(){}
      });
      
  • Node.js的适用场景?

  • (如果会用node)知道route, middleware, cluster, nodemon, pm2, server-side rendering么?

  • 解释一下 Backbone 的 MVC 实现方式?

  • 什么是“前端路由”?什么时候适合使用“前端路由”? “前端路由”有哪些优点和缺点?

知道什么是webkit么? 知道怎么用浏览器的各种工具来调试和debug代码么?

    Chrome,Safari浏览器内核。
  • 如何测试前端代码么? 知道BDD, TDD, Unit Test么? 知道怎么测试你的前端工程么(mocha, sinon, jasmin, qUnit..)?

  • 前端templating(Mustache, underscore, handlebars)是干嘛的, 怎么用?

  • 简述一下 Handlebars 的基本用法?

  • 简述一下 Handlerbars 的对模板的基本处理流程, 如何编译的?如何缓存的?

  • 检测浏览器版本版本有哪些方式?

        功能检测、userAgent特征检测
    
        比如:navigator.userAgent
        //"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36
          (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
    
  • What is a Polyfill?

polyfill 是“在旧版浏览器上复制标准 API 的 JavaScript 补充”,可以动态地加载 JavaScript 代码或库,在不支持这些标准 API 的浏览器中模拟它们。
例如,geolocation(地理位置)polyfill 可以在 navigator 对象上添加全局的 geolocation 对象,还能添加 getCurrentPosition 函数以及“坐标”回调对象,所有这些都是 W3C 地理位置 API 定义的对象和函数。因为 polyfill 模拟标准 API,所以能够以一种面向所有浏览器未来的方式针对这些 API 进行开发,一旦对这些 API 的支持变成绝对大多数,则可以方便地去掉 polyfill,无需做任何额外工作。
  • 做的项目中,有没有用过或自己实现一些 polyfill 方案(兼容性处理方案)?

    比如: html5shiv、Geolocation、Placeholder

  • 我们给一个dom同时绑定两个点击事件,一个用捕获,一个用冒泡。会执行几次事件,会先执行冒泡还是捕获?

  • 使用JS实现获取文件扩展名?

    function getFileExtension(filename) {
    return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
    }

    String.lastIndexOf() 方法返回指定值(本例中的'.')在调用该方法的字符串中最后出现的位置,如果没找到则返回 -1。
    对于'filename'和'.hiddenfile',lastIndexOf的返回值分别为0和-1无符号右移操作符(»>) 将-1转换为4294967295,将-2转换为4294967294,这个方法可以保证边缘情况时文件名不变。
    String.prototype.slice() 从上面计算的索引处提取文件的扩展名。如果索引比文件名的长度大,结果为""。

ECMAScript6 相关

  • Object.is() 与原来的比较操作符“ ===”、“ ==”的区别?

        两等号判等,会在比较时进行类型转换;
        三等号判等(判断严格),比较时不进行隐式类型转换,(类型不同则会返回false);
    
        Object.is 在三等号判等的基础上特别处理了 NaN 、-0 和 +0 ,保证 -0 和 +0 不再相同,
        但 Object.is(NaN, NaN) 会返回 true.
    
         Object.is 应被认为有其特殊的用途,而不能用它认为它比其它的相等对比更宽松或严格。
    

前端框架相关

  • react-router 路由系统的实现原理?

  • React中如何解决第三方类库的问题?

其他问题

  • 原来公司工作流程是怎么样的,如何与其他人协作的?如何夸部门合作的?

  • 你遇到过比较难的技术问题是?你是如何解决的?

  • 设计模式 知道什么是singleton, factory, strategy, decrator么?

  • 常使用的库有哪些?常用的前端开发工具?开发过什么应用或组件?

  • 页面重构怎么操作?

        网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。
        也就是说是在不改变UI的情况下,对网站进行优化,在扩展的同时保持一致的UI。
    
        对于传统的网站来说重构通常是:
    
        表格(table)布局改为DIV+CSS
        使网站前端兼容于现代浏览器(针对于不合规范的CSS、如对IE6有效的)
        对于移动平台的优化
        针对于SEO进行优化
        深层次的网站重构应该考虑的方面
    
        减少代码间的耦合
        让代码保持弹性
        严格按规范编写代码
        设计可扩展的API
        代替旧有的框架、语言(如VB)
        增强用户体验
        通常来说对于速度的优化也包含在重构中
    
        压缩JS、CSS、image等前端资源(通常是由服务器来解决)
        程序的性能优化(如数据读写)
        采用CDN来加速资源加载
        对于JS DOM的优化
        HTTP服务器的文件缓存
    
  • 列举IE与其他浏览器不一样的特性?

    1、事件不同之处:

           触发事件的元素被认为是目标(target)。而在 IE 中,目标包含在 event 对象的 srcElement 属性;

        获取字符代码、如果按键代表一个字符(shift、ctrl、alt除外),IE 的 keyCode 会返回字符代码(Unicode),DOM 中按键的代码和字符是分离的,要获取字符代码,需要使用 charCode 属性;

        阻止某个事件的默认行为,IE 中阻止某个事件的默认行为,必须将 `returnValue` 属性设置为 false,Mozilla 中,需要调用 preventDefault() 方法;

        停止事件冒泡,IE 中阻止事件进一步冒泡,需要设置 cancelBubble 为 true,Mozzilla 中,需要调用 stopPropagation();
  • 99%的网站都需要被重构是那本书上写的?

        网站重构:应用web标准进行设计(第2版)
    
  • 什么叫优雅降级和渐进增强?

        优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会针对旧版本的IE进行降级处理了,使之在旧式浏览器上以某种形式降级体验却不至于完全不能用。
        如:border-shadow
    
        渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新版本浏览器才支持的功能,向页面增加不影响基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用。
        如:默认使用flash上传,但如果浏览器支持 HTML5 的文件上传功能,则使用HTML5实现更好的体验;
    
  • 是否了解公钥加密和私钥加密。

        一般情况下是指私钥用于对数据进行签名,公钥用于对签名进行验证;
        HTTP网站在浏览器端用公钥加密敏感数据,然后在服务器端再用私钥解密。
    
  • WEB应用从服务器主动推送Data到客户端有那些方式?

        html5提供的Websocket
        不可见的iframe
        WebSocket通过Flash
        XHR长时间连接
        XHR Multipart Streaming
        
                        
                        

你可能感兴趣的:(javascript,面试,笔试,前端,jquery)