1、复制变量值与参数传递
函数都有一个arguments对象,函数的参数就是这个对象的一个元素,该对象类似数组,可以通过数组访问的方式访问其中的元素。而所谓的函数的参数定义,就是将对应位置的arguments起了一个名字,便于在函数中引用,因此:
函数的参数是函数的局部变量。
函数传值的过程,就是将 外部变量的值 复制到 arguments的某个元素 中,该元素是函数的局部变量。
换言之,JS函数都是按值传递,无论是基本类型还是引用类型。虽然引用类型是按值传递给函数内部,但是在函数内部访问对象时依然按引用访问。
举个例子:
object1=object2.将object2复制给object1,此时是将object2的指针创建一个副本,然后将这个副本赋值给object1,此时object1,object2指向同一个对象。
function f (o){
o.name="a";
o=new Object();
o.name="b";
}
var p=new Object();
f(p);
alert(p.name);//"a"
因为对象p将值传给了o,即将对象p指向堆空间的指针创建了一个副本,并赋值给了o,这样在给o的属性赋值时,会按引用找到对象,从而改变了那个对象的属性的值。此时,p的属性name也同样被改变了,因为p本来就跟o对应的同一个对象。
而当o=new Object时,又将新创建的Object的指针创建了一个副本,将这个副本给了o,此时o.name,按引用找到的对象就是new Object新创建的对象了。由于函数的参数是函数的局部变量,函数执行完后,该参数就被清除了。
基本变量赋值时,也是给其创建一个副本,然后进行赋值,两个变量虽然值相同,但是没有什么关系。而传递参数时也是一样,因为函数传参的本质是将 外部的值 复制到 参数变量中。I
2、执行环境和作用域
执行环境定义了变量或函数有权访问的其他数据。每个执行环境都有一个环境变量,称之为变量对象,环境中所定义的变量和函数都保存在其中。有一个最外围的执行环境称为全局环境。其他环境都是在一个函数内的局部环境。在Web浏览器中,最外围的环境是window,每个函数都有一个自己的环境。
【作用域链】当代码在环境中执行时,会创建一个变量的作用域链,当访问一个变量或函数时,会沿着当前执行环境向外查找,直到找到最外层,如果没有找到,则报错。
var 变量=1;
fuction 函数1(){
var 函数1里的变量=变量;
function 函数2(){
var 函数2里的变量=函数1里的变量;
函数1里的变量=变量;
变量=函数2里的变量;
}
函数2();
};
函数1();
最里层的函数2可以访问该函数外部环境中的所有变量。但是外部环境不能访问内部环境的变量。即只能从里往外检索。
【函数赋值】如果用var定义,则将变量存入最近的执行环境的变量对象中,其作为局部变量。没有用var定义的变量,会存入全局执行环境的变量对象中,该变量就是全局变量。
3、没有块级作用域
类似于if(){ }, for(){} 这样的块,其内部定义的变量,比如for(var i =0;i<10;i++)中的i,在for循环之外还是有效的,这点与Java不同。
4、引用类型的值和引用类型
引用类型的值(对象)是引用类型的一个实例。引用类型是一种数据结构,包含数据和功能。引用类型 相当于类,但是不具有其他oo语音的特征,因此被称为 对象定义 更确切,因为它描述的是 一类对象 所具有的方法和属性。
Object类型是JS内置的一种引用类型。
【对象创建】
var p=new Object();//()可省略,但不推荐
p.name="可以";// 给对象增加属性。
如果需要定义大量属性,可以使用对象字面量表示法:
var p={
name:"Nike",
age:"18"
};
var p={};与var p=new Object()等价。但不会调用Object的构造函数。
【访问属性的方法】访问属性除了使用圆点法——object.propertyname外,还可以使用方括号 object[propertyname],使用场景是当propertyname是动态的,比如通过遍历对象属性赋值或取值时。
Array类型
【创建数组】 var a=new Array();
参数可以是n个:
n=1:如果是数字,表示创建数字表示的长度的数组。如果是非数字,表示只包含这个值的单值数组
n>1:表示包含n个值的数组,这n个值就是这n个参数,比如new Array("a","b","c")
n=0:数组是动态可扩展的。
其中new 可以省略,变成 var a=Array;
数组字面量:var a=["a","b",""];
数组的length不是只读的。
【栈方法】 a.push("a","b");在数组末尾追加;a.pop() 返回数组最后一项,该项从数组中被去掉。
【队列方法】a.shift();返回数组第一项,该项从数组中被去掉;a.unshift(“a”,"b")在数组前面添加。
【反转数组】a.reverse();
【数组排序】a.sort默认升序排列。 a.sort(compare) 其中compare可以实现比较方法function compare(value1,value2)
【操作方法】concat slice splice
Function类型
Function类型也是引用类型,那么每个函数都是Function类型的实例。而且有自己的属性和方法(所以函数里也可以定义函数)。由于函数是Function类型的对象,对象可以赋值给不同变量,因此同一个函数可以有不同的名字(赋值给不同变量),这个名字是找到函数去执行的指针而已。
函数声明语法定义 function f(){
}与 函数表达式定义(将函数的指针复制给变量f)
var f=function(){
}相同。区别是:在全局执行环境加载数据时,会首先加载函数声明,因此函数的执行在函数声明前后没有关系。而函数表达式是代码执行到表达式时才会加载,因此函数执行必须在表达式之后。
f传递的是函数的指针。f()表示函数执行。
【this】函数内部有一个特殊对象this,其值与函数执行环境有关。this引用的是执行函数操作的对象。如果在全局环境中执行,那么this就引用的是全局环境中的变量;如果在函数是一个对象的方法,那么this引用的就是对象的属性。
c="a";
function f(){alert(this.c);};
f(); //相当于window对象执行f,因此其中的this引用的是window,this.c="a"
var o={c:"b"};
o.f=f; //将f的指针赋给o的函数f
o.f(); //执行时指向f函数,此时this引用的是o,因此this.c=“b”
由于函数是Function类型的对象,因此无论是在哪个环境下执行的f,都是同一个函数。
5、原型(Prototype)
每个函数都有一个原型属性,该属性是一个对象。用途是包含可以由特定类型的所有实例共享的属性和方法。每个原型属性都会自动获得一个constructor(构造函数)属性,这个属性包含一个指针,该指针指向Prototype属性所在的函数。(这样函数和原型属性双向引用)
当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性__proto__),指向构造函数的原型属性。(这样实例可以找到构造函数的原型属性,间接与构造函数关联)
函数都是对象。构造函数是对象,构造函数通过new创造出的函数也是对象。
//函数表达式法定义函数,
var f=function(){}; //f是一个对象。等价于 var f=new Function(参数0-n,函数体); 函数是一个对象,函数名是一个指针
f();//执行在window环境下。
function F(){}; //与var F=function(){}等价
F.prototype.name="a";
F.prototype.sayName=function(){alert(this.name)};
F();//F自己本身就是个函数,可以执行,这样执行就是成为window的对象
var o=new F();
o.sayName(); //o是一个对象,o执行F的内部的一个函数sayName
JS原生的Function函数也是个对象,也是通过new Function可以实例化成一个个function函数对象。
6、闭包和私有作用域
闭包就是能够访问外部变量,但是其内部变量对外部不可见。
(function(){
私有作用域
})();
上面这个表示一个匿名函数,后面那对括号表示函数立即执行,和var f=function(){}; f();一样。只是这个函数没有名字,也就没法调用,在函数外加上括号后,变成了表达式,就可以执行了。
var f=(function(){})();同理。
这个用法很普遍,特别对于大型项目,防止过多变量污染全局空间,也可以解决没有块作用域的情况(前面讲的for语句的例子):http://segmentfault.com/q/1010000000135703
相关推荐
JavaScript高级程序设计是每个前端开发者深入理解这门语言所必经之路。这篇学习笔记将带你探索JavaScript的核心概念,包括变量、数据类型、控制流、函数、对象和类等,这些都是构建复杂应用程序的基础。 首先,我们...
### HTML5高级程序设计学习笔记 #### 一、HTML5新增结构标签 在HTML5中,为了更好地组织页面内容并增强语义性,引入了一系列新的结构标签,这些标签不仅能够帮助开发者更清晰地定义页面的不同部分,同时也为搜索...
JavaScript高级程序设计是每个前端开发者必经的技术领域,DOM(Document Object Model)是网页内容的结构化表示,它为HTML或XML文档提供了一个统一的、与语言无关的接口。这篇学习笔记主要围绕DOM基础展开,涵盖了...
javacript高级程序设计的个人学习总结,涉及到很多javascript的高级特性
以上只是JavaScript高级程序设计中的一部分内容,实际的学习笔记会更深入地探讨这些主题,包括异常处理、作用域链、闭包、异步编程(如回调函数、Promise、async/await)、模块系统(CommonJS、ES modules)、正则...
这份“JavaScript高级程序设计---笔记归类.pdf”文档显然详细整理了JavaScript的关键知识点,包括ECMAScript规范、DOM操作、数据类型、运算符、流程控制语句、函数以及面向对象编程等。 首先,ECMAScript是...
这本“JavaScript高级程序设计第四版”的学习笔记涵盖了JavaScript的各个方面,旨在帮助学生、开发者以及对编程感兴趣的人深入理解这一强大的脚本语言。这份笔记是针对毕设、课设、项目实训等实践性学习场景编写的,...
JavaScript高级程序设计学习笔记(四)主要探讨了JavaScript中的引用类型、Function类型、函数的声明与定义、函数表达式以及一些基本包装类型的相关知识。在JavaScript中,函数不仅仅是代码块,它们也是对象,具备...
在本节中,我们将深入探讨JavaScript的高级程序设计,特别是关注"第四章(js高级程序设计学习笔记)----2"的主题。这一章很可能涵盖了JavaScript的核心概念,包括原型链(Prototype Chaining)。通过阅读名为...
1、对象再认识 (1)对象属性和特性 什么是属性(Property),什么是特性(Attribute),这有什么区别?我不想也不会从语义学上去区分,对于这系列文章来说,属性就是组成对象的一个部分,广义上也包括对象的方法...
JavaScript中的数据类型分为两大类:基本类型(Primitive Types)和引用类型(Reference Types)。基本类型包括Undefined、Null、Boolean、Number、String,它们是按值访问的,即变量直接保存了值本身。例如,当你...
可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,...
在深入探讨JavaScript编程语言之前,...在《JavaScript高级程序设计》这本书中,作者深入探讨了这些概念,并提供了一系列实用的编程技巧和最佳实践,这对于任何希望深化JavaScript知识的开发者来说都是一份宝贵的资源。
通过上述的知识点介绍,我们可以看到,JavaScript中的错误处理与调试是一个复杂但非常重要的主题。掌握这些知识将大大提高开发者的效率,并优化用户的体验。在实际开发过程中,开发者应该编写详尽的测试用例,并结合...
网页程序设计是一门涵盖多个关键技术领域的综合学科,主要包括HTML(超文本标记语言...总的来说,这个压缩包提供了一个全面的网页程序设计学习路径,涵盖了从基础到高级的关键技术,适合希望进入网页开发领域的学习者。