Javascript中函数相关知识点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javascript中函数相关知识点相关的知识,希望对你有一定的参考价值。

PS:本内容属于javascript中基础知识,适合初学者或者基础知识不牢固者

/**
* ECMAScript中所有函数的参数都是 “按值传递” 的,也就是说,把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到两一个变量一样。
* 值得注意的是,访问变量有“按值”和”按引用”两种方式,而参数只能 “按值传递”。
* PS1:在向参数传递基本类型的值时,被传递的值会被复制给一个局部变量(即命名参数,或者还用ECMAScript的概念来说,就是arguments对象中的一个元素)。
* 在向参数传递引用类型的值的时候,
* 会把这个值在内存中的地址复制给一个局部变量,因为这个局部变量的变化会反映在函数的外部。
* **/

function addTen(num){
num +=10;
return num;
}
var count = 20;
var result = addTen(count);
console.log(count); // 20
console.log(result); // 30

//
function setName(obj){
obj.name = "Andy";
}
var person = new Object();
setName(person);
console.log(person.name); // Andy

// 解析:以上代码中创建了一个对象,并将起保存在了变量person中,然后,这个变量被传递到setName()函数中之后就被复制给了obj。这个函数内部,obj和person引用的是同一个对象。
// 换句话说,即使这个变量是按值传递的,obj也会按引用来访问同一个对象。
// 很多人错误的认为:在局部作用域中修改的对象会在全局作用域中反映出来,就说明参数是按引用传递的。为了证明对象是按值传递的,我们看下面一个例子:

function setName2(obj){
obj.name = ‘Andy‘;
obj = new Object();
obj.name = ‘Greg‘;
}
var person2 = new Object();
setName2(person2);
console.log(person2.name);// Andy

/**
* 如果person是按引用传递的,那么person就会自动被修改为指向其name属性值为“Greg”的新对象。
* 但是,当接下来再访问person.name时,显示的值仍然是“Andy”。这说明即使在函数内部修改了参数的值,但原始的引用仍然保持未变。
* 实际上,当再函数内部重新obj时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁;
* **/

/**
* 执行环境以及作用域
* 每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。而在函数执行之后,栈将其环境弹出,把控制权返回给之前的执行环境。
* ECMAScript程序中的执行流正式由这个方便的机制控制着。
*
* **/

/**
* 管理内存:
* 确保占用最少的内存可以让页面获得更好的性能。而优化内存占用的最佳方式,就是为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其值设置为null来释放其引用--这个做法叫做解除引用。
* 这一做法适用于大多数全局变量和全局对象的属性。局部变量会在他们离开执行环境时被解除引用。
* 不过,解除一个值的引用并不意味着自动回收该值所占用的内存。解除引用的真正作用是让值脱离执行环境,以便垃圾收集器下次运行时将其回收。
* **/

function createPerson(name){
var localPerson = new Object();
localPerson.name = name;
console.log(localPerson.name); // Andy
return localPerson;
}
var globalPerson = createPerson(‘Andy‘);
globalPerson = null;

/**
* 引用类型:
* 引用类型的值(对象)是引用类型的一个实例。在ECMASript中,引用类型是一种数据结构,用于将数据和功能组织在一起。它也常被称为“类”。但这种称呼并不妥当。
* 1,Object类型
* 创建Object实例的方式有两种。第一种是使用new操作符后跟Object构造函数如:
* var person = new Object();
* person.name = "Andy";
* person.age = ‘27‘;
* 另外一种方式是使用对象字面量表示法
* var person ={
* name:"Andy",
* age :27
* }
* 一般说来,访问对象属性时使用的都是点表示法,这也是很多面向对象语言中通用的语法。不过在Js中也可以使用方括号表示法来访问对象的属性。在使用方括号语法时,应该将要访问的属性以字符串的形式放在
* 方括号里。如
* alert(person["name"]); >>>> alert(person.name)
* 从功能上看,这两种访问对象属性的方法没有任何区别,但方括号语法的主要优点是可以通过变量来访问属性,如:
* var proptrtyName = ‘name‘;
* alert(person[proptrtyName]);
* 如果属性名中包含会导致语法错误的字符,或者属性名使用的是关键字或保留字,也可以使用方括号表示法:如
* person["first name"] = "Andy"; // 由于“first name”中包含一个空格,所以不能用点表示法来访问它。
* **/

/**
* 2,Array类型
* 创建数组的基本方式有两种。
* 第一种是使用Array构造函数,
* var color = new Array();
*第二种是使用数组字面量表示法。
* var color = ["red","blue","green"];
*
* 数组的length属性很有特点--它不是只读的。因此,通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项
* **/
var colors = ["red","blue","green"];
colors.length =2;
console.log(colors[2]); // undefined;
// 如果将其length属性设置为大于数组项数的值,则新增的每一个项都会取得undefined的值
var colors2=["red","blue","green"];
colors2.length =4;
console.log(colors2[3]); // undefined;
// 所以,利用length属性也可以方便地在数组末尾添加新项;

/**
* 检测数组
* if( value instanceof Array ){
* // TO DO...
* }
* 不过,如果网页中包含多个框架,那实际上就存在两个以上不同的全局执行环境,从而存在两个以上不同版本的Array构造函数。如果你从一个框架向另一个框架传入一个数组,那么传入的数组与在第二个
* 框架中原生创建的数组分别具有各自不同的构造函数。
* 为了解决这个问题,ECMAScript5新增了Array.isArray()方法;
*
* if (Array.isArray(value)){ 支持Array.isArray() 方法的浏览器有IE9+,.....
* // TO DO...
* }
* 如果要解决浏览器兼容性问题,由于在任何值上调用Object原生的toString()方法,都会返回一个【object NativeConstrucotrName】格式的字符串,每个类在内部都有一个[[Class]]属性,
* 这个属性中就指定了上述字符串中的构造函数名。
* 由于原生数组的构造函数名与全局作用域无关,因此使用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]‘;
}

/**
* 转换方法:
* 其实,所有对象都具有toLocaleString()/toString()/valueOf()方法,其中,调用数组的toString()方法会返回有数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串。而调用
* valueOf()返回的还是数组。
* **/
var colors3 = ["red","blue","green"];
console.log(colors3.toString()); // red,blue,green
console.log(colors3.valueOf()); // ["red", "blue", "green"]
console.log(colors3); //["red", "blue", "green"]
// console.log(colors3)要接收字符串参数,所以它会在后台调用toString()方法,由此会得到与直接调用toString()方法相同的结果;

/**
* 栈方法:(后进先出)
* ECMAScript数组也提供了一种让数组的行为类似于其他数据结构的方法。具体说来,数组可以表现的像栈一样,后者是一种可以限制插入和删除项的数据结构。
* ECMAScript为数组专门提供了push()和pop()方法,以便实现类似栈的行为。
* push():把他们逐个添加到数组末尾,并返回 修改后数组的长度 ;
* pop():方法则从数组末尾移除最后一项,然后返回 移除的项 ;
* **/

/**
* 队列方法:(先进先出)
* 队列在列表的末端添加项,从列表的前端移除项。
* shift():它能够移除数组中的第一个项并返回 该项 ,同时将数组长度减1
* unshift():
* **/

var colors4 =new Array();
var count4= colors4.push(‘red‘,‘green‘);
console.log(count4); //2
count4 = colors4.push(‘black‘);
console.log(count4); //3

var item = colors4.shift();
console.log(item); // ‘red‘
console.log(colors4.length); // 2

var colors5 =new Array();
var count5 = colors5.unshift(‘red‘,‘green‘);
console.log(count5)
count5 = colors5.unshift(‘black‘)
console.log(colors5)

以上是关于Javascript中函数相关知识点的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript的相关知识点学习与实践一

JavaScript笔记--- ECMAScript初步(变量,函数,数据类型等相关知识)

javascript相关知识

JavaScript高级函数相关知识:函数纯函数柯里化严格模式

JavaScript高级函数相关知识:函数纯函数柯里化严格模式

JavaScript中数组的基础知识和相关方法