function B(age, name) {
this.age = age;
A.call(this, name);
}
B.prototype = new A('test');
var foo = new B(18, 'test');
console.log(foo.name); // test
console.log(foo.age); // 18
console.log(foo.sayName); // test
6. JS变量提升
请看下面代码
var bar = 1;
function test() {
console.log(bar); // undefined
var bar = 2;
console.log(bar); // 2
}
test();
if (!String.prototype.repeatify) {
String.prototype.repeatify = function(count = 1) {
let result = '';
let currentValue = this.toString();
for (let i = 0; i < count; i++) {
result += currentValue;
}
return result;
};
}
JavaScript 基础
1. JavaScript的数据类型
2. 闭包closure
简单的说闭包就是一个函数能够访问外部函数的变量。比如:
a函数中的b函数就是闭包,b函数可以使用a函数中的局部变量、参数,最典型的闭包应该是下面这样:将定义在函数中的函数作为返回值:
闭包的另外一种作用就是隔离作用域,请看下面这段代码:
上面这段代码的执行结果是2,2,而不是0,1,因为在for循环结束后才执行setTimeout中的函数,i的值已经变成了2,这就是没有隔离作用域造成的。
请看下面改造过后的代码:
这样就会输出0、1,其中的立即执行函数创建了一个作用域(函数作用域),隔离了外界的作用域。
闭包的缺点是,内部闭包函数可以访问外部函数的变量,会导致外部函数的变量不能被释放,如果闭包嵌套过多,会导致内存释放不及时,进而导致内存占用过高,所以要合理使用闭包。
3. 作用域和作用域链
JS的作用域指的是变量的作用范围,内部作用域由函数的形参、实参、局部变量以及函数构成,内部作用域和外部作用域一层层的链接起来形成作用域链,当在函数内部要访问一个变量时,首先查找函数自己内部作用域有没有这个变量,如果没有就到这个对象的原型中去查找,如果还是没有的话,就到该作用域所在的作用域中找,直到window所在的作用域,每个函数在声明的时候就默认有一个外部作用域存在了,比如:
bar找t变量的过程就是,先到自己的内部作用域中找,发现没有找到,然后到bar所在的最近的外部变量中找,也就是foo的内部作用域,还是没有找到,再到window的作用域中找,结果找到了。
4. call和apply
call
和apply
,建设要改变fn函数内部的this指向,指向obj,那么可以使用fn.call(obj)
,或者fn.apply(obj)
。bind
函数。 var bar = fn.bind(obj), 那么,fn中的this就指向obj对象了,bind函数就返回新的函数,这个函数内部的this指针指向obj对象。5. 继承()
先定义一个A,
原型继承
这样B通过原型继承了A,在new B的时候,foo中有个隐藏的属性proto指向构造函数的prototype对象,在这里是A对象实例,A对象里面也有一个隐藏的属性proto,指向A构造函数的prototype对象,这个对象里面又有一个proto指向Object的prototype
这种方式的缺第一个缺点是所有子类共享父类实例,如果某一个子类修改了父类,其他的子类在继承的时候,会造成意想不到的后果。第二个缺点是在构造子类实例的时候,不能给父类传递参数。
构造函数继承
采用这种方式继承是把A中的属性加到this上面,这样name相当于就是B的属性,sayName不在A的构造函数中,所以访问不到sayName。这种方法的缺点是父类的prototype中的函数不能复用。
原型继承+构造函数继承
6. JS变量提升
请看下面代码
为什么在test函数中会出现上述结果呢,这就是JavaScript的变量提升了,虽然变量bar的定义在后面,不过浏览器在解析的时候,会把变量的定义放到最前面,上面的test函数相当于:
再看一个例子:
事件模型、事件绑定、委托机制
内存泄漏与垃圾回收
跨域
同源策略
Web安全
12. 前端性能优化(提高网页加载速度,降低白屏率)
13. Promise
例子
repeatify
功能,当传入一个整数n时,会返回重复n次的字符串的结果。 例如: