前端错题集(1)

JavaScript

类型

  • 七种数据类型:Undefined、Null、Boolean、Number、String、Object、(Symbol)
  • 五种基本数据类型:Undefined、Null、Boolean Number、String
  • typeof六种返回格式:undefined、boolean、number、string、object、function
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    var f = function g() {
    return 23;
    };
    typeof f;//function
    typeof f();//number
    typeof g;//undefined
    typeof g();//ReferenceError,g is not defined
    //""代表字符串
    console.log(1+ "2"+"2");//122
    console.log(1+ +"2"+"2");//32
    console.log("A"- "B"+"2");//NaN2
    console.log("A"- "B"+2);//NaN
    var x = new Boolean(false);//对象
    //true
    if (x) {
    alert('hi');
    }
    var y = Boolean(0);//值
    //false
    if (y) {
    alert('hello');
    }

    变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var a,b;
    (function(){
    alert(a);//undefined
    alert(b);//undefined
    var a=b=3;//a是局部变量,而b是全局变量
    alert(a);//3
    alert(b);//3
    })();
    alert(a);//undefined
    alert(b);//3

    创建数组

    1
    2
    3
    4
    var arr=[1,2,3];     
    var arr=new Array(1,2,3);
    var arr=new Array(12);//如果只有一个数,代表数组的length是12个
    var arr=new Array(0);//清空数组

框架

AngularJS

  • 大大减少了对DOM的访问
  • 前端mvc,极大降低前端开发的耦合
  • 实现了数据双向绑定
  • 实现了依赖注入
  • compile绑定DOM,link绑定数据
  • 调用compile函数将得到一个编译好的template函数,他将会调用从所有指令中搜集而来的link函数
  • ng-if会移除dom,生成dom
  • ng-show只是改变其display属性
  • ng-class是AngularJS预设的一个指令,用于动态自定义dom元素的css class name
  • control间通信最好使用广播
  • AngularJS的服务是一个单例对象或函数,对外提供特定的功能

JQuery

  • 极大的丰富了DOM操作
    1
    2
    3
    4
    5
    6
    7
    8
    alert($(window).height()); //浏览器当前窗口可视区域高度
    alert($(document).height()); //浏览器当前窗口文档的高度
    alert($(document.body).height());//浏览器当前窗口文档body的高度
    alert($(document.body).outerHeight(true));//浏览器当前窗口文档body的总高度 包括border padding margin
    alert($(window).width()); //浏览器当前窗口可视区域宽度
    alert($(document).width());//浏览器当前窗口文档对象宽度
    alert($(document.body).width());//浏览器当前窗口文档body的宽度
    alert($(document.body).outerWidth(true));//浏览器当前窗口文档body的总宽度 包括border padding margin

Bootstrap

  • 应该将被包裹的元素放到navbar-collapse类中
  • 表单应该放置于navbar-form内
  • 可以使用navbar-left和navbar-right来对齐导航条
  • 可以使用navbar-fixed-top和navbar-fixed-bottom来将导航条固定到顶部或底enter image description here

浏览器支持

IE

  • 混淆了 DOM 对象属性(property)及 HTML 标签属性(attribute),造成了对 setAttribute、getAttribute 的不正确实现
  • 仅 IE 中的 createElement 方法支持传入 HTML String 做参数

FireFox

  • 不支持 DOM 对象的 outerHTML、innerText(用textContent替代)、outerText 属性

异步编程Asynchronous Programming

  • 回调函数,这是异步编程最基本的方法。
    1
    2
    3
    4
    5
    6
    7
    8
    f1();
    f2();
    function f1(callback){
    setTimeout(function() {
    // f1的任务代码
    callback();
    }, 1000);
    }
  • 事件监听,另一种思路是采用事件驱动模式。任务的执行不取决于代码的顺序,而取决于某个事件是否发生。
    1
    2
    3
    4
    5
    6
    7
    f1.on('done', f2);
    function f1(){
    setTimeout(function() {
    // f1的任务代码
    f1.trigger('done');
    }, 1000);
    }
  • 发布/订阅,上一节的”事件”,完全可以理解成”信号”。
    1
    2
    3
    4
    5
    6
    7
    8
    jQuery.subscribe("done", f2);
    function f1(){
    setTimeout(function() {
    // f1的任务代码
    jQuery.publish("done");
    }, 1000);
    }
    jQuery.unsubscribe("done", f2);
  • Promises对象,Promises 对象是CommonJS 工作组提出的一种规范,目的是为异步编程提供统一接口。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    f1().then(f2);
    function f1(){
    var dfd = $.Deferred();
    setTimeout(function () {
    // f1的任务代码
    dfd.resolve();
    }, 500);
    return dfd.promise;
    }
    //指定多个回调函数:
    f1().then(f2).then(f3);
    //指定发生错误时的回调函数:
    f1().then(f2).fail(f3);

AJAX与Flash

  • AJAX的优势:可搜索性、开放性、费用、易用性、易于开发。
  • Flash的优势:多媒体处理、兼容性、矢量图形、客户端资源调度
  • AJAX的劣势:它可能破坏浏览器的后退功能;使用动态页面更新使得用户难于将某个特定的状态保存到收藏夹中,不过这些都有相关方法解决
  • Flash的劣势:二进制格式;格式私有;flash文件经常会很大,用户第一次使用的时候需要忍耐较长的等待时间;性能问题

作用域Scope

  • scope: true和transclude: true会创建新的子作用域,并且进行原型继承
  • scope: {…} 会创建新的独立作用域,不会进行原型继承
  • 默认情况下创建directive使用了scope: false,不会创建子作用域
  • For不会形成作用域

原型Prototype

javascript语言实现继承机制的核心就是prototype,而不是Java语言那样的类式继承。Javascript 解析引擎在读取一个Object的属性的值时,会沿着原型链向上寻找,如果最终没有找到,则该属性值为undefined; 如果最终找到该属性的值,则返回结果。与这个过程不同的是,当javascript解析引擎执行“给一个Object的某个属性赋值”的时候,如果当前Object存在该属性,则改写该属性的值,如果当前的Object本身并不存在该属性,则赋值该属性的值。

用HasOwnProperty判断原型链属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function Person() {
}

Person.prototype.name="Nicholas";
Person.prototype.age=29;
Person.prototype.sayName=function(){
alert(this.name);
}

var person1=new Person();
person1.name="Greg";

var person2=new Person();

console.log(person1.hasOwnProperty("name"));//true
console.log(person2.hasOwnProperty("name"));//false

console.log("name" in person1);//true
console.log("name" in person2);//true

for (var prop in person1) {
console.log(prop);//name age sayName
}

function hasPrototypeProperty(object,pro) {//如此可判断存在于原型中的属性
return (!object.hasOwnProperty(pro))&&(pro in object);
}
console.log(hasPrototypeProperty(person1,"name"));//false
console.log(hasPrototypeProperty(person2,"name"));//true

原型链与this

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// 实现a.name = “name1”; b.name = “name2”;
function obj(name){
if(name){
this.name = name;//填写语句
}
return this;
}
obj.prototype.name = "name2";//填写语句
var a = obj("name1");
var b = new obj;

console.log(a.name); // name1
console.log(window.name); // name1
console.log(b.name); // name2

//一般函数直接调用,默认this执行全局window|global
//通过obj('name1')调用,返回this引用,并传给a, 此时a等于window对象,即可输出属性name值

//new操作, new obj 等价于 new obj() ,实例化一个对象,这时this指向obj,要拿到b.name的值
//需要保证name属性存在,属性查找原则是先查找当前实例有没有属性,如果有就直接使用,如果没有就到原型上面找,再没有就接着原型链一步一步,这里为了和a.name作属性区别,使用了if(name)有条件地构建this的属性name
//所以,现在实例name属性提供给a使用,原型上的name提供给b使用。

//两个变体
function obj(name){
//if(name){
this.name = name;
//}
return this;
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj;

console.log(a.name);//name1
console.log(window.name);//name1
console.log(b.name);//undefined
// 这时b实例已经有属性name,但参数name为undefined ,所以这时可以把this.name属性删掉,这样就能去原型找name了
function obj(name){
//if(name){
this.name = name;
//}
return this;
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj;

console.log(a.name);//name1
console.log(window.name);//name1
delete b.name;
console.log(b.name);//name2


// 再试试 new obj('myName') 传个参数
function obj(name){
//if(name){
this.name = name;
//}
return this;
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj('myName');

console.log(a.name);//name1
console.log(window.name);//name1
console.log(b.name);//myName

延时

1
2
window.setTimeout(checkState, 10000);//延时10S执行
window.setTimeout(checkState(), 10000);//加了圆括弧相当于函数表达式,会立即执行,执行的结果作为返回值传递给setTimeout

过滤器

输出对象中值大于2的key的数组

1
2
3
4
5
6
7
8
var data = {a: 1, b: 2, c: 3, d: 4};
Object.keys(data).filter(function(x) {
return data[x]>2;
})
//filter的第二个参数是index, 这里可以用arguments[1]来取到
Object.keys(data).filter(function(x) {
return arguments[1]>=2
})