一、原型链
"a".__proto__.__proto__.__proto__===null//true
'a'.__proto__ === String.prototype //true
@数字的原型
1.__proto__.__proto__.__proto__//直接报错
VM300:2 Uncaught SyntaxError: Unexpected token ILLEGAL(…)InjectedScript._evaluateOn @ VM45:878InjectedScript._evaluateAndWrap @ VM45:811InjectedScript.evaluate @ VM45:667
new Number(1).__proto__.__proto__.__proto__===null
true
Number.prototype.__proto__===Object.prototype二、new发生了什么?
构造函数调用,返回一个实例对象,并实现了继承
创建对象用的,构造函数尽量不要有返回值。
@具体是什么
function Person(name,age){
this.name = name;
this.age= age;
this.fn=()=>{ console.log('方法')}
}
Person.prototype={
fn1:function(){console.log("fn1")}
}
var p=new Person('andy');//可以不加小括号,不传参的话
p.name//"andy"
p.fn()//"方法"@实现一个构造函数(入参是构造函数,与其他参数,返回一个对象)
function _new(/*constr,params*/){//...arg更方便
let args=[...arguments];
let constructor=args.shift();
var newObj={};
newObj.__proto__=constructor.prototype;
//let newObj = Object.create(constructor);//issue
let result = constructor.apply(newObj ,args);
console.log("result",result,"newObj ",newObj )
return typeof result === "object" ? result: newObj
}
var p = _new(Person,'andy',22);new总结四步:
- 提取参数,第一个参数为构造函数,剩余的为其他参数(构造函数私有属性,方法);
- 创建对象,并把其原型指向构造函数的原型;
- 调用构造函数,并把this指向新创建的对象;
- 返回此对象,如果构造函数返回一个对象,则返回此对象(不建议构造函数有返回值),否则返回新创建的对象;
三、闭包
首先,从作用域出发,es6之前,JS有俩种作用域,
第一,全局作用域
第二,函数作用域
闭包就是一个函数可以访问另外一个函数内的变量。突破了JS的函数作用域。
阮一峰老师给出:
闭包就是能够读取其他函数内部变量的函数
特点:
1.使变量不被污染,一直保存在内存中,不会被GC垃圾回收机制回收,容易造成内存泄漏,不建议使用
2.私有变量
案例:
function add() {
var x = 1;
console.log(++x);
}
add(); //执行输出2,
add(); //执行还是输出2,
//----------
function add() {
var x = 1;
return function() {
console.log(++x);
};
}
var num = add();
num(); //输出2
num(); //输出3
num(); //输出4
for (var i = 0; i < 5; ++i) {
setTimeout(function() {
console.log(i + " ");
}, 100);
}
//------------将 setTimeout 放在立即执行函数中,将 i 值作为参数传递给包裹函数,创建新闭包
for (var i = 0; i < 5; ++i) {
(function(i) {
setTimeout(function() {
console.log(i + " ");
}, 100);
})(i);
}
四、GC垃圾回收机制
- 引用计数(缺点,循环引用问题)
- 标记清除(JS用的这种)
比如,一个函数调用时,分配好内存空间,打标。调用完清除标记,并被回收。
五、性能优化结合VUE优化(单独一篇文章总结)