想复习一下javascript高级程序设计一书的内容,写下了下面的笔记,都是比较细的点,想到什么就写什么了,可能有点略杂。javascript
1.Array的length
不只是可读的,并且是可写的。这就意味着能够经过修改length
来直接裁剪数组。若是length
直接改大,那么没有赋值的地方为undefined
java
var a = [1,2,3]; a.length=2; a;//[1,2] a.length=3; a;//[1,2,undefined]
2.Array.concat()能够接受不少个参数,而且也支持类型不同的。将会返回链接以后的副本,不会修改原来的数组数组
var a = [1,2,3]; var b = a.concat('a',[3,4,5],1); a;//[1,2,3] b;//[1,2,3,'a',3,4,5,1]
3.splice()
函数app
参数数目 | 功能 |
---|---|
两个参数Array.splice(startPos,delNum) |
进行删除操做,第一个参数表示起始位置,第二个表示删除的个数 |
多个参数Array.splice(startPos,delNum,*insetElems) |
删除并插入,前两个参数同上,以后的参数为在删除的位置须要插入的元素。若是第二个参数为0,仅进行插入操做。 |
Function
和字符串String
1.要擅于利用arguments.callee进行解耦。咱们在写递归函数的时候都会在函数内部调用自身函数,这时咱们若是使用自身的函数名,函数内部就和函数名有耦合。咱们直接使用arguments.callee
就能够访问到函数名并进行调用函数
function addAll(n){ if(n==1){return 1;} return n+addAll(n-1); return n+arguments.callee(n-1);//better! } var addAll_1 = addAll; addAll_1(3);//error
2.引用类型和基本包装类型最主要的就是对象的生存期。若是是使用new
建立的引用类型实例,那么执行流会一直生存到当前做用域结束。若是是自动建立的则其基本包装类对象只存在一瞬间。this
var s = "sad"; s.color = "red"; s.color;//null
3.使用new调用基本包装类性的构造函数和直接调用同名函数的结果是不同的。编码
var number = Number("123"); typeof number;//number var number2 = new Number("123"); typeof number2;//Object
4.因为字符串也是相似一个数组,咱们想要对string
使用Array
方法,可使用call
或者apply
prototype
var str = '123'; Array.prototype.map.call(str,function(ele){console.log(ele);}
经过这个方法可使用数组的不少方法,好比filter
,forEach
等。不过貌似不少地方均可以用相似这种模式。
5.数组的方法:trim()
,concat()
不少都不会修改原来数组的内容,只是建立副本并返回。
6.使用Global
对象的encodeURIComponent()
函数对全部非字母数字进行编码。decodeURIComponent()
进行解码。这个以前写爬虫就爬到了不少相似于unicode
的码u5168,或者在网页URI中的一些查询字符%E5%93%88%E5%93%88
之类的也能够经过这个进行解码,还算是比较好用的一个函数啦。
7.利用bind()
函数进行过一次绑定以后就不再可以进行第二次绑定了。也就是说this已经被固定下来了。设计
var a = {name:"A"} var b = {name:"B"} function getName(){console.log(this.name);} var getA = getName.bind(a); getA();//A var getB = getA.bind(b); getB();//A
8.只要是继承的,进行instanceof
检测的时候会返回true
code
a instanceof Object;//true undefined instanceof Object;//false null instanceof Object;//false
Object
类的属性的属性属性的属性就是指Object
的属性的一些特性。分为数据属性和访问器属性。数据属性是用来存储数据数值的,而访问器属性通常进行get/set
操做,而不能进行数据的存储。
其中,数据属性分为四个:
1. [[Configurable]]表示可否经过delete删除属性从而从新定义属性 2. [[Enumerable]]表示可否经过for-in循环返回属性。 3. [[Writable]]表示可否修改属性的值 4. [[Value]]表示值
访问器属性
1.[[Configurable]]:默认为true。表示可否经过delete删除属性从而从新定义属性,可否修改属性特性,或者可否把属性修改成访问器属性; 2.[[Enumerable]]:默认为true。表示可否经过for-in循环返回属性; 3.[[Get]]:读取属性时调用的函数,默认为undefined; 4.[[Set]]:写入属性时调用的函数,默认为undefined。
不能直接添加这些属性。只能用Object.defineProperty()
或者Object.defineProperties()
进行设置。例子以下
var a = {_name:123} Object.defineProperty(a, 'name', { get:function(){ return "我是"+this._name; }, set:function(newVal){ if(newVal>20){ this._name=newVal; } } })
这里a并无name
这个属性,可是经过get()
创建了从name
到_name
的映射。可使得数据属性的操做更加灵活。
下面是同时进行多个属性的设置的语法示例:(writable
设置为false
表示不能进行值的修改。)
Object.defineProperties( a,{_name:{value:23,writable:false},{name:{get:function(){return this._name;},set:function(){}} } } )
能够经过对象实例来访问保存在原型中的值,可是不能经过对象实例来重写原型中的值,他会在实例的属性中添加这个值而且遮盖掉原型链中的值。可是经过__proto__.prop
就能够访问到原型链中的prop
属性。
即使是在实例中设置属性为null也不会消除对原型属性的遮蔽。除非使用delete
function Person(){ } Person.prototype.name="aa"; var a = new Person(); var b = new Person(); a.name="bb"; b.name;//"aa" a.name=null; a.name;//null a.__proto__.name;//"aa" a.__proto__.name="bb"; b.name;//"bb"
能够经过hasOwnProperty()
来获取到实例非原型链中是否有这个属性。
若是要判断实例有这个属性(包括原型链中的属性)用in
这个操做符。
经过for-in
循环返回的是对象可以访问到的(包括原型链),并且enumerable设置为true的属性
var c={name:"123",age:23}; Object.defineProperty(c,'name',{enumerable:false}) for(ele in c){console.log(ele);}//only age
若是要返回全部实例非原型链属性(不论是否能够枚举)
Object.keys(obj)//将返回全部可枚举的,属于实例对象的属性的属性名数组。 Object.getOwnPropertyNames(obj);//返回的是全部实例属性(不包括原型链),不论是否可枚举