JavaScript基本概念(五)

xiaoxiao2021-02-28  110

八、函数

1、定义

使用function关键字来定义,可以用在函数定义表达式或者函数声明语句里。

function functionName(arg0, arg1, ... ,argN) { statements }

在定义时,可以不必指定是否有返回值。

2、调用

1)作为函数调用

function myFunction(a, b) { return a * b; } myFunction(10, 2); //返回 20

2)作为方法调用(方法,就是保存在一个对象的属性里的函数。)

var myObject = { firstName:"John", lastName: "Doe", fullName: function () { //这里的this的值为myObject对象 return this.firstName + " " + this.lastName; } } myObject.fullName() // 返回 "John Doe"

3)作为构造函数调用

// 构造函数 function myFunction(arg1, arg2) { this.firstName = arg1; this.lastName = arg2; } var x = new myFunction("John","Doe"); x.firstName; // 返回 "John"

4)通过call()和apply()间接调用函数

两个方法的第一个参数必须是对象本身。

call()方法使用它自有的实参列表作为函数的实参。apply()方法要求以数组的形式传入参数。 // call()方法 function myFunction1(a, b) { return a * b; } alert(myFunction1.call(this, 10, 2)); // 返回 20 // apply()方法 function myFunction2(a, b) { return a * b; } myArray = [10,2]; alert(myFunction2.apply(this, myArray)); // 返回 20

3、参数

1)JavaScript函数对参数的值(arguments)没有进行任何的检查。

ECMAScript函数不介意传递进来多少个参数,也不在乎传进来的参数是什么数据类型。即使定义的函数只接收两个参数,在调用时这个函数时未必一定要传递两个参数。

2)函数显式参数与隐藏参数

函数显式参数在函数定义时列出。函数隐藏参数在函数调用时传递给函数真正的值。

3)默认参数

没有传递值的命名参数将自动被赋予undefined值。

4)arguments对象

包含了函数调用的参数数组,arguments对象与数组类似,但它并不是Array实例。通过访问arguments对象的length属性可以知道有多少个参数传递给了函数。arguments对象可以与命名参数一起使用。

5)ECMAScript中的所有参数传递的都是值,不可能通过引用传递参数。

var x = 1; // 通过值传递参数 function myFunction(x) { x++; //修改参数x的值,将不会修改在函数外定义的变量 x console.log(x); } myFunction(x); // 2 console.log(x); // 1

在上面的代码中,在函数中调用的参数是函数的参数。如果修改参数的值,将不会修改参数的初始值(在函数外定义)。 在JavaScript中,可以引用对象的值。我们在函数内部修改对象的属性就会修改初始的值,修改对象属性可作用于函数外部(全局变量)。具体看下面这个例子。

var obj = {x:1}; // 通过对象传递参数 function myFunction(obj) { obj.x++; //修改参数对象obj.x的值,函数外定义的obj也将会被修改 console.log(obj.x); } myFunction(obj); // 2 console.log(obj.x); // 2

4、没有重载

九、基本类型和引用类型的值

区别基本类型值引用类型值含义简单的数据段由多个值构成的对象访问方式按值访问,可以操作保存在变量中的实际的值按引用访问,不能直接操作对象的内存空间,只能操作对象的引用动态的属性不能添加属性可以动态地添加属性和方法从一个变量向另一个变量复制值,即变量的复制两个变量独立,互不影响两个变量引用同一个对象,改其中一个变量会影响另一个传递参数如同变量的复制把被传递的值复制给一个局部变量检测类型的工具typeof操作符instanceof操作符

十、执行环境和作用域

1、执行环境

1)定义了变量或函数有权访问的其他数据,决定了它们各自的行为。 每个函数都有自己的执行环境。

2)执行环境的类型有两种:全局和局部(函数)。 全局执行环境是最外围的一个执行环境。比如在Web浏览器中,全局执行环境被认为是window对象。

2、作用域链

1)当代码在一个环境中执行时,会创建变量对象的一个作用域链。

2)作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。换句话说,作用域为可访问变量、对象、函数的集合。作用域链的前端始终都是当前执行的代码所在环境的变量对象。 可以将作用域链形象地比喻成一个按照出场顺序演出的名单,演出指的就是整个环境,名单上的人就是一个个对象,按照出演顺序依次表演,即为对变量的有序访问。

3)延长作用域链:在作用链前端添加。

try-catch语句的catch块:创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。with语句:将指定的对象添加到作用域链中。

3、在内部环境可以通过作用域链访问所有的外部环境,但是外部环境不能访问内部环境中的任何变量和函数。这些环境之间的联系是线性、有次序的。每个环境都可以向上搜索作用域链以查询变量和函数名。

4、JavaScript没有块级作用域。

对于if语句和for语句中创建的变量,在外部环境中也可以使用。

5、使用var声明的变量会自动添加到最接近的环境中。

变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的,即在函数内声明的所有变量在函数体内始终是可见的。特别注意的是,变量在声明之前甚至已经可用。举个例子:

var scope = "global"; function f() { console.log(scope); //输出undefined var scope = "local"; //变量在这里赋初始值,但变量本身在整个函数体内任何地方都是有定义的 //所以在上一行语句中,输出undefined,而不是global console.log(scope); //输出local }

6、标识符解析

是沿着作用域链一级一级地搜索标识符的过程。始终从作用域链的前端开始,逐级向后,直到找到标识符为止,如果找不到,通常会发生错误。 如果局部环境中存在着同名标识符,就不会使用位于父环境中的标识符。

十一、垃圾收集

1、JavaScript是一门具有自动垃圾收集机制的编程语言。

2、垃圾收集算法:

标记清除(最常用):给当前不使用的值加上标记,然后再回收其内存。引用计数(不太常用):跟踪记录每个值被引用的次数。当代码中存在循环引用现象时,此算法会导致问题。

3、解除引用

一旦数据不再有用,通过将其值设置为null来释放其引用。 这一做法适用于大多数全局变量和全局对象的属性。 局部变量会在它们离开执行环境时自动被解除引用。

转载请注明原文地址: https://www.6miu.com/read-58781.html

最新回复(0)