javascript高级程序设计(4-5)章笔记
2016-04-24 18:32
375 查看
之前看过一遍js高程,有些基础还不牢固,单身狗周末又没地方去,开始重新撸一遍JS高程,写点笔记,防止以后忘了!
高程:函数内部重写obj时,这个变量引用的就是一个局部对象,而局部对象会在函数执行完毕后立即被销毁。个人理解就是函数作用域,外部环境无法访问内部的私有变量 ,包括arguments,其实相当于参数被重新定义成对象,但是外部的对象未变化,所以是按值传递,即对象的深度复制。
2.每个函数都有自己的执行环境 ,当执行流进入一个函数时,函数的环境就会给推入一个环境栈中(后进先出)。当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。每个环境多都可以向上搜索作用域链,以查询变量和函数名,(访问局部变量比访问全局变量要快,javascript引擎在优化标识符查村做的很ok,可以忽略不计)。
解除值的引用不会马上自动回收该值所占用的内存,是让值脱离执行环境,以便垃圾收集器下次运行将其回收。
从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量指向同一个对象。
每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链
通过对象字面量定义对象时,实际上不会调用Object构造函数(Firefox2及更早版本会),即不会调用new实例化对象。【ES3之前的正则字面量存在bug,循环test某个字符串,一次为真一次为假,ES5已修正(P105页)】
以上代码要返回true就,value必须是数组,而且还必须与Array构造函数在同个全局作用域中,(切记,Array是window的属性),如果value在另个frame定义的数组,那么以上代码就会返回false。
在任何值上调用Object原声的toString()方法,都会返回一个[object NativeConstructorName]格式的字符串,由于原生数组的构造函数与全局作用域无关,因此toString()就能保证返回一致的值。
在Web开发中能够区分原生与非原生javascript对象非常重要,这样才能确切知道某个对象到底有哪些功能,但是Object.prototype.toString()本身也能被重写。
so要访问函数的指针而不执行函数的话,必须去掉函数名后面的那对圆括号。
函数声明与函数表达式
js解析器会率先读取函数声明(function declaration hosting),并使其在执行任何代码之前可用,至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解析执行。
作为值的函数
函数内部属性
函数内部有两个特殊对象:arguments和this,arguments.callee指向拥有arguments对象的函数(ES6已弃用)。
this引用的是函数据以执行的环境对象,即函数调用,蝴蝶书上讲过有四种调用模式
1.方法调用模式,this指向当前方法的对象;
2.函数调用模式,this被绑定到全局对象,客户端即window;
3.构造器调用模式,this被绑定到实例化的新对象上;
4.apply/call调用模式,第一个参数都是要被绑定给this,第二个参数apply是数组,call([thisObj[,arg1[, arg2[, [,.argN]]]]])。
函数属性和方法
每个函数都包含两个属性: length(函数希望接收的命名参数的个数) 和 prototype。
对于ECMAScript中的引用类型而言,prototype是保存她们所有实例方法的真正所在。在ES5中,prototype属性是不可枚举的,(非原生的prototype属性可枚举,即人为添加上去的,在google测试过)因此使用for-in无法发现。
ES5还定义了一个方法: bind()。这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
上述可以解析成三个步骤
1.创建String类型的一个实例;
2.在实例上调用指定的方法;
3.销毁这个实例
执行代码类似如下:
引用类型与基本包装类型的主要区别就是对象的生存期。使用new操作符创建的引用类型实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型,则只存在于一行代码的执行瞬间,然后理解被销毁。
4.变量 作用域和内存问题
ECMAScript中所有函数的参数都是按值传递的(不区分基本类型和引用类型)
引用类型是按引用传递的,函数的参数全部按值传递,有点蒙逼,看代码//基本类型值没问题 function add(num) { num += 10; return num; } var count =20 ; console.log(add(count));//30 //看不出来 /*高程给的解释:在这个函数内部,obj和person引用的是同一个对象。 *换句话说,即使这个对象是按值传递的,obj也会按引用来方位同一个对象*/ function setName (obj) { obj.name = 'kenny'; } var person = new Object(); setName(person); // 'kenny' //函数内部重新定义obj对象 function setName (obj) { obj.name = 'kenny'; obj = new Object(); obj.name = 'gaga'; } var person = new Object(); setName(person); // 'kenny'
高程:函数内部重写obj时,这个变量引用的就是一个局部对象,而局部对象会在函数执行完毕后立即被销毁。个人理解就是函数作用域,外部环境无法访问内部的私有变量 ,包括arguments,其实相当于参数被重新定义成对象,但是外部的对象未变化,所以是按值传递,即对象的深度复制。
执行环境及作用域
1.每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中, 虽然无法访问此对象,但js解析器会在后台使用它,(chorme 控制台js断点的时候,当前作用定义的变量和函数都能在当前执行环境查看,soga)。2.每个函数都有自己的执行环境 ,当执行流进入一个函数时,函数的环境就会给推入一个环境栈中(后进先出)。当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。每个环境多都可以向上搜索作用域链,以查询变量和函数名,(访问局部变量比访问全局变量要快,javascript引擎在优化标识符查村做的很ok,可以忽略不计)。
垃圾收集
标记清除(大部分浏览器以此来实现)和引用计数管理内存
一旦数据不再引用,最好通过将其设置为null来释放引用——俗称解除引用。适用于大多数全局变量和全局对象的属性,局部变量会在他们离开执行环境时自动解除引用。//执行完毕,person函数内的对象会自动销毁, function person (name) { var localPerson = new Object(); localPerson.name = name; return localPerson; } var gloablPerson = person('kenny'); gloablPerson = null;
解除值的引用不会马上自动回收该值所占用的内存,是让值脱离执行环境,以便垃圾收集器下次运行将其回收。
小结
基本类型值占据固定大小的空间,因此保存在栈中,引用类型的值是对象,保存在堆内存中。从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量指向同一个对象。
每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链
5.引用类型
对象字面量通过对象字面量定义对象时,实际上不会调用Object构造函数(Firefox2及更早版本会),即不会调用new实例化对象。【ES3之前的正则字面量存在bug,循环test某个字符串,一次为真一次为假,ES5已修正(P105页)】
安全的类型检测
var isArray = value instanceof Array;
以上代码要返回true就,value必须是数组,而且还必须与Array构造函数在同个全局作用域中,(切记,Array是window的属性),如果value在另个frame定义的数组,那么以上代码就会返回false。
在任何值上调用Object原声的toString()方法,都会返回一个[object NativeConstructorName]格式的字符串,由于原生数组的构造函数与全局作用域无关,因此toString()就能保证返回一致的值。
function isArray(value) { return Object.prototype.toString.call(value) === '[object Array]'; } function isFunction(value) { return Object.prototype.toString.call(value) === '[object Function]'; } function isRegExp(value) { return Object.prototype.toString.call(value) === '[object RegExp]'; }
在Web开发中能够区分原生与非原生javascript对象非常重要,这样才能确切知道某个对象到底有哪些功能,但是Object.prototype.toString()本身也能被重写。
Function类型
每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。//函数是对象,函数名是指针 function sum(num1, num2) { return num1 + num2; } console.log(sum(10,10)); //20 var anotherSum = sum; //使用不带圆括号的函数名是访问函数指针,而非调用函数 console.log(anotherSum(10,10)); //20 sum = null; //设置其他值也一样 console.log(anotherSum(10, 10))//20
so要访问函数的指针而不执行函数的话,必须去掉函数名后面的那对圆括号。
函数声明与函数表达式
js解析器会率先读取函数声明(function declaration hosting),并使其在执行任何代码之前可用,至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解析执行。
作为值的函数
function createComparisonFunction(propertyName) { return function(object1, object2){ var value1 = object1[propertyName]; var value2 = object2[propertyName]; if (value1 < value2){ return -1; } else if (value1 > value2){ return 1; } else { return 0; } }; } var data = [{name: "Zachary", age: 28}, {name: "Nicholas", age: 29}]; data.sort(createComparisonFunction("name")); alert(data[0].name); //Nicholas data.sort(createComparisonFunction("age")); alert(data[0].name); //Zachary
函数内部属性
函数内部有两个特殊对象:arguments和this,arguments.callee指向拥有arguments对象的函数(ES6已弃用)。
this引用的是函数据以执行的环境对象,即函数调用,蝴蝶书上讲过有四种调用模式
1.方法调用模式,this指向当前方法的对象;
2.函数调用模式,this被绑定到全局对象,客户端即window;
3.构造器调用模式,this被绑定到实例化的新对象上;
4.apply/call调用模式,第一个参数都是要被绑定给this,第二个参数apply是数组,call([thisObj[,arg1[, arg2[, [,.argN]]]]])。
函数属性和方法
每个函数都包含两个属性: length(函数希望接收的命名参数的个数) 和 prototype。
对于ECMAScript中的引用类型而言,prototype是保存她们所有实例方法的真正所在。在ES5中,prototype属性是不可枚举的,(非原生的prototype属性可枚举,即人为添加上去的,在google测试过)因此使用for-in无法发现。
ES5还定义了一个方法: bind()。这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。
基本包装类型
var s1 = 'some text'; var s2 = s1.substring(2);
上述可以解析成三个步骤
1.创建String类型的一个实例;
2.在实例上调用指定的方法;
3.销毁这个实例
执行代码类似如下:
var s1 = new String('some text'); var s2 = s1.substring(2); s1 = null;
引用类型与基本包装类型的主要区别就是对象的生存期。使用new操作符创建的引用类型实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型,则只存在于一行代码的执行瞬间,然后理解被销毁。
小结
在所有代码执行之前,作用域中就已经存在两个内置对象:Global 和Math。在大多数ECMAScript视线中都不能直接访问Global对象;不过WEB浏览器实现了承担该角色的window对象。全局变量和函数都是Global对象的属性。Math对象提供了很多属性和方法,用于辅助完成复杂的数学计算。相关文章推荐
- javascript实现下雪效果
- JavaScript常用字符串与数组扩展函数小结
- 数据可视化:dc.js的使用
- js获取浏览器高度和宽度值(多浏览器)
- 一个帖子解决服务器与客户端传递对象的问题,JSON解析两种方法
- 字典转化为 json 字符串
- [读书笔记]JavaScript 闭包(Closures)
- ihone手机拍摄图片,js(canvas,input)上传的方向问题-----更不喜欢它了
- jsp form事件和 js 函数不能并行
- JavaScript 图片URL转DataURL,DataURL转Blob
- Javascript闭包(Closure)
- 介绍 JSON
- JavaScript中typeof
- 使用JS,获取URL中指定参数的值
- js跨站之 window.name方法
- JSP编译指令和动作指令
- 【JSOI2016】飞机调度
- js document.body.scrollTop的用法
- js常用正则表达式
- 【JS 设计模式 】用组合模式来实现树形导航--JS代码结构思路分析(二)