1. 立即执行函数,会生成私有变量,防止变量污染
2. 闭包 内部函数可以访问外部函数的变量,把函数返回去,闭包可以保护内部的变量,但也会造成内存的泄漏 ,所以需要不用之后置为null
3. 原型链
3.1 构造函数里的属性的优先级比原型链的高
3.2 面向对象编程的时候, js没有类的概念,可以用函数替代
3.3 constructor实际就是对应的那个函数
3.4 prototype是按引用传递的,可以使用Object.create()创建原型链的副本,那子类就不能使用父类以后在prototype上添加的属性和方法了?可以使用
4. 数值、字符串、布尔类型按值传递,数组、对象按引用传递
5. 改变this的方法: call、apply、bind(bind是返回一个新的方法)
var test = {
name: 30,
init: function(){
console.log(this.name);
}
}
var data = { name: 40;};
var n = test.init.bind(data);
n();
6. 函数提升、变量提升,函数提升的优先级要比变量高。
一个小圈套
(function(){
var a = 20;
var b = c = a; //var b, c = 20; 这样外部就取不到了
})();
alert(c); //20; c相当于全局变量
一个大圈套
+function(){
alert(a);
a();
var a = function(){
console.log(1);
}
function a(){
console.log(2);
}
alert(a);
a();
var c = d = a;
}()
alert(d);
alert(c);
函数提升的优先级高,所以alert a的值第一次是函数,第二次是变量,d属于全局变量,c属于局部变量
7. jq内部有很多经典的写法,如:模块化编程的概念、闭包
es5有些新增的功能:
object的方法
a. Object.getPrototypeOf() 返回的对象实际就是这个对象的原型,即获取实例的原型对象
function Person(){}
var person1 = new Person();
Object.getPrototypeOf(person1) == Person.prototype; //true
Object.getPrototypeOf(Person) //不知道取的是个什么
console里执行的结果
Object.getPrototypeOf(Person)
ƒ () { [native code] }
Object.getPrototypeOf(Object)
ƒ () { [native code] }
Object.getPrototypeOf(Object) == Object.getPrototypeOf(Person)
true
js的原始类
b. Object.getOwnPropertyDescriptor(实例名字,属性名字); 获取实例自身的属性值,prototype上的取不到
c. Object.getOwnPropertyDescriptors(实例名字); 获取实例自身所有的属性的键值对
d. Object.getOwnPropertyNames(实例名字); 获取实例自身所有的属性名
e. Object.create(proto),一般用来实现继承,返回新对象
function create(o){
function F(){};
F.prototype = o;
return new F();
}
Object.create(),相当于create函数。Object.create还有第二个参数,定义的是自身的属性,会覆盖原对象的属性,相当于是在this上直接添加的属性。等价的function如下:第二个参数有格式限制 {name:{value: 'wenwen'}}
这里有个需要注意的点,Object.create方法的第二个参数相当于 Object.defineProperties() 的第二个参数,所以默认读写枚举都是false,
function create(o){
function F(){};
F.prototype = o;
return new F();
}
目前没有第二个参数的替代方法。
// Shape - superclass
function Shape() {
this.x = 0;
this.y = 0;
}
// superclass method
Shape.prototype.move = function(x, y) {
this.x += x;
this.y += y;
console.info('Shape moved.');
};
// Rectangle - subclass
function Rectangle() {
Shape.call(this); // call super constructor.
}
// subclass extends superclass
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
var rect = new Rectangle();
console.log('Is rect an instance of Rectangle?',
rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?',
rect instanceof Shape); // true
rect.move(1, 1); // Outputs, 'Shape moved.'
一般不用Object.create创建对象,因为不方便,创建的话是这样的
var obj = Object.create({foo:1}, //原型上的属性
{
bar: {value: 2}, //不可枚举的属性
baz: {value: 3, enumerable: true}
})
console.log(obj);
f. Object.defineProperty(obj, prop, descriptor
); 增加新属性或修改原有的属性值, 返回原来的对象。这种方式添加的属性如果不指定
enumerable: false,configurable: false, writable: false,这些属性的话,默认都是false,所以不可修改,不可枚举。
可以用这种方式定义不能被修改的属性。
g. Object.defineProperties(obj, props); 同上
h. Object.seal() 这个方法是让对象密封,不可删除,不可添加属性,原有的可修改的属性还是可以修改的
i. Object.isSealed() 判断对象是否被密封
j. Object.is(); 判断两个值(对象)是否相等,直接比较,不会做类型转换
Object.is('foo', 'foo'); // true
Object.is(window, window); // true
Object.is('foo', 'bar'); // false
Object.is([], []); // false
var test = { a: 1 };
Object.is(test, test); // true
Object.is(null, null); // true
// 特例
Object.is(0, -0); // false
Object.is(-0, -0); // true
Object.is(NaN, 0/0); // true
Object.is(NaN, NaN); //true
k. Object.freeze(); 将对象冻结,不能修改、删除。但是如果属性是对象的话,该属性是可以修改的,因为这种冻结是浅冻结,要想所有的都冻结的话还要循环执行freeze方法。
l. Object.isFrozen() 判断一个对象是否被冻结
m. Object.preventExtensions(); 该方法让一个对象变得不可扩展,即不可以添加新的对象。
var obj = Object.preventExtensions({}); 创建一个空的不可扩展的对象,则该对象也是被冻结的。
如果对象是不可扩展,且属性是不可配置和修改的话,该对象也是冻结对象。
n. Object.isExtensible(); 判断对象是否可扩展。preventExtensions()、seal()、 freeze() 方法使对象变为不可扩展。
o. Object.entries(), Object.keys(), Object.values(). 这三个方法又可以和迭代器和生成器联系起来。
以上方法具体参见 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
Array新增的方法
增加了every、some 、forEach、filter 、indexOf、lastIndexOf、isArray、map、reduce、reduceRight方法
PS: 还有其他方法 Function.prototype.bind、String.prototype.trim、Date.now