1.复制变量值

  在说函数前,我觉得需要先说说关于变量值的复制,以便后面的理解。

  复制基本类型的值:

  当一个变量复制另外一个值为基本类型的变量时,两个变量可以参与任何操作而不会互相影响

var num1 = 5;
var num2 = num1;
console.log('num1的值是:' + num1); //
console.log('num2的值是:' + num2); // num1 = 10;
console.log('num1修改后,num1的值是:' + num1); //
console.log('num1修改后,num2的值是:' + num2); //

  复制引用类型的值:

  当一个变量复制另外一个值为引用类型的变量时,改变其中一个变量的值,就会影响另外一个变量

var obj1 = {
name: 'Mike'
};
var obj2 = obj1;
console.log('obj1.name:' + obj1.name); // Mike
console.log('obj2.name:' + obj2.name); // Mike obj1.name = 'Alice';
console.log('改变后的obj1.name:' + obj1.name); // Alice
console.log('改变后的obj2.name:' + obj2.name); // Alice
var arr1 = [1,2,3];
var arr2 = arr1;
console.log(arr1); // [1,2,3]
console.log(arr2); // [1,2,3] arr2[3] = 4;
console.log('改变后的arr1:' + arr1); // [1,2,3,4]
console.log('改变后的arr2:' + arr2); // [1,2,3,4]

2.函数声明与函数表达式

  

add(10,10); // 20
function add(num1,num2) {
return num1 + num2;
}  

  以上是函数声明,函数声明的方式创建的函数会提前

add(10,10);  // Error
var add = function(num1,num2) {
return num1 + num2;
}

  以上是函数表达式,函数表达式的方式创建的函数不会提前

3.传递参数

  函数的参数,其实可以看成是一个局部变量。所以当我们传递参数,特别是当参数是一个对象的时候,我们需要注意执行函数后,对原来值的影响。

  

var count = 10;

function add(num) {
num += 10;
console.log(num);
}
add(count); //
console.log(count); //

  对于上面的代码,可以看成是传递的参数是一个数值之类的基本类型值的时候,var num = count,然后按照基本类型值传递。

var person = {
name: '小红'
};
function setName(obj) {
obj.name = '小明';
console.log(obj.name); // '小明'
}
setName(person);
console.log(person.name); // '小明'

  当传递的参数是一个对象时,此时var obj = person,两个变量都指向同一个对象,改变obj.name就会改变person.name,所以按照引用类型传递

var person2 = {
name: '花花'
};
function setName2(obj) {
obj.name = '豆豆';
console.log(obj.name); // '豆豆'
console.log(person2.name); // '豆豆'
obj = {
name: '黑黑'
};
console.log(obj.name); // '黑黑'
}
setName2(person2);
console.log(person2.name); // '豆豆'

  首先是var obj = person2,两个变量都指向同一个对象,所以按照引用类型传递。

  然而重写obj后,obj指向了另外的一个对象,所以不会再次改变对象person2。

4.arguments对象

  arguments对象表示函数传入的所有参数,不是定义函数时的写的参数:

  

function fun1(num1,num2,num3) {
return arguments.length;
}
fun1(1); // function fun2(num1,num2) {
return arguments.length;
}
fun2(22,33); //

  arguments拥有length属性,不过arguments只是一个伪数组,并非一个真正的数组。

  arguments还有一个callee属性,该属性指向拥有这个arguments对象的函数,arguments.callee()相当于调用函数本身,用它可以实现更松散的耦合:

function fun1(num) {
if (num <= 1) {
return 1;
} else {
return num * fun1(num-1);
}
} function fun2(num) {
if (num <= 1) {
return 1;
} else {
return num * arguments.callee(num-1);
}
} // 实现更松散的耦合
var fun3 = fun2;
fun2 = function() {
return 0;
};
console.log(fun3(5)); //
console.log(fun2(5)); //

  从上面的代码可以看出,即使重写了函数fun2,函数fun3也能打印正确的值。

  函数对象还有一个caller属性,表示调用当前函数的函数:

function fun1() {
fun2();
}
function fun2() {
console.log(arguments.callee.caller);
}
fun1(); // 打印出函数fun1

5.apply()、call()和bind()

  先说用法,apply()方法接受两个参数,第一个是运行函数的作用域,第二个是函数的参数数组,可以是Array的实例,也可以是arguments对象。call()用法与apply()一样,不过传递第二个参数时,写法有些差别。

window.color = 'blue';
var obj = {
color: 'red'
}; function fun1(num) {
  console.log(this.color);
  return num;
}
function fun2() {
  return fun1.apply(this,arguments);
}
fun1.apply(obj); // red
fun2(2); // blue 2

  当apply()的第一个参数是this的时候,则this表示的是当前函数所在的作用域,这里是在window作用域下,所以fun2函数的this.color是blue。

  对于apply()、call()和bind()3个方法,我所知道的真正强大的地方就是在于能够扩充函数赖以运行的作用域。

  他们的区别是bind 是返回对应函数,便于稍后调用,apply 、call 则是立即调用 :

var obj = {
age: 21,
sayAge: function () {
return this.age;
}
};
var copySay = obj.sayAge.bind(obj);
copySay(); // 21 注意这里加了括号 var copySay2 = obj.sayAge.apply(obj);
copySay2; // 21 注意这里没加括号

  关于apply()和call()更详细的用法与区别,大家可以看看其他前辈的博客,很多也很详细,在这里我就不再赘述,只是通过自己的理解,记录了下红皮书上的大体和关键点。

菜鸟快飞之JavaScript函数的更多相关文章

  1. 菜鸟快飞之JavaScript对象、原型、继承(三)

    正文之前需要声明的一点是,菜鸟系列博文全是基于ES5的,不考虑ES6甚至更高版本. 继承 由于我个人不是学计算机的,所以对于很多东西只是知其然,不知其所以然.就像这个继承,刚开始学JavaScript ...

  2. 菜鸟快飞之JavaScript对象、原型、继承(一)

    有前辈说过,在JavaScript中,一切皆对象.由此可见,作为JavaScript的核心之一,对象是有多么重要.虽然今天走亲戚有点累,但还是得写写这个对象,免得吃几天好的,就又忘光了. 1.创建对象 ...

  3. 菜鸟快飞之JavaScript对象、原型、继承(二)

    上一节写了创建对象的三种方法,而其中通过函数创建对象的方式又有三种模式,分别是工厂模式.构造函数模式.原型模式.而这三种模式最常用的则是原型模式.还是上栗子: 工厂模式: function Fun1( ...

  4. javaScript函数节流与函数防抖

    javaScript函数节流与防抖之区别 函数防抖(debounce)与函数节流(throttle)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟.假死或卡顿 ...

  5. JavaScript函数、对象和数组

    一.JavaScript函数 1.定义函数:函数的通用语法如下 function function_name([parameter [, ...]]) { statements; } 由关键字func ...

  6. ABP(现代ASP.NET样板开发框架)系列之21、ABP展现层——Javascript函数库

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之21.ABP展现层——Javascript函数库 ABP是“ASP.NET Boilerplate Project ...

  7. JavaScript权威设计--JavaScript函数(简要学习笔记十一)

    1.函数调用的四种方式 第三种:构造函数调用 如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内.这和函数调用和方法调用是一致的.但如果构造函数没有形参,JavaScri ...

  8. JavaScript 函数

    JavaScript 函数 介绍:函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块.嗯,就像Java中封装的方法一样. 将脚本编写为函数,就可以避免页面载入时执行该脚本. 函数包含着一些代码 ...

  9. javascript 函数初探 (一)--- 神马是函数

    神马是函数? 所谓函数,本质上是一种代码的分组形式.我们可以通过这种形式赋予某组代码一个名字,以便与之后的调用.下面,我们来示范以下函数的声明: function sum(a, b){ var c = ...

随机推荐

  1. Android快乐贪吃蛇游戏实战项目开发教程-03虚拟方向键(二)绘制一个三角形

    该系列教程概述与目录:http://www.cnblogs.com/chengyujia/p/5787111.html 一.绘制三角形 在上一篇文章中,我们已经新建了虚拟方向键的自定义控件Direct ...

  2. Asp.Net 5 新增公告仓库

    一直以来Asp.Net 5 都没有一个比较统一的公告页,对于一个在日夜更新的项目来说,很多人经常会遇到问题但是不知道去哪里寻找帮助,现在Asp.Net 5 项目组新增了一个公告仓库来解决这个问题.  ...

  3. 物联网实验4 alljoyn物联网实验之手机局域网控制设备

    AllJoyn开源物联网协议框架,官方描述是一个能够使连接设备之间进行互操作的通用软件框架和系统服务核心集,也是一个跨制造商来创建动态近端网络的软件应用.高通已经将该项目捐赠给了一个名为“AllSee ...

  4. 云计算之路-阿里云上:“黑色1秒”最新线索——w3tp与w3dt

    向大家分享一下最近排查“黑色1秒”问题的进展,“黑色1秒”的问题表现详见什么是黑色1秒. 1. 发生在w3wp进程内 判断依据:“黑色1秒”期间,http.sys的HTTP Service Reque ...

  5. Entity Framework 6 Recipes 2nd Edition(13-9)译 -> 避免Include

    问题 你想不用Include()方法,立即加载一下相关的集合,并想通过EF的CodeFirst方式实现. 解决方案 假设你有一个如Figure 13-14所示的模型: Figure 13-14. A ...

  6. Spring学习记录(十四)---JDBC基本操作

    先看一些定义: 在Spring JDBC模块中,所有的类可以被分到四个单独的包:1.core即核心包,它包含了JDBC的核心功能.此包内有很多重要的类,包括:JdbcTemplate类.SimpleJ ...

  7. 本地存储之cookie

    cookie概述: Cookie 在计算机中是个存储在浏览器目录中的文本文件,当浏览器运行时,存储在 RAM 中发挥作用 (此种 Cookies 称作 Session Cookies), 一旦用户从该 ...

  8. dom addeventlistener与id 绑定事件的区别

    文档中有写. //addEventListener() 方法用于向指定元素添加事件句柄. //提示: 使用 removeEventListener() 方法来移除 addEventListener() ...

  9. 3. SVM分类器求解(1)——Lagrange duality

    先抛开上面的二次规划问题,先来看看存在等式约束的极值问题求法,比如下面的最优化问题: 目标函数是f(w),下面是等式约束.通常解法是引入拉格朗日算子,这里使用来表示算子,得到拉格朗日公式为 是等式约束 ...

  10. 【JS】javascript 正则表达式 大全 总结

    javascript 正则表达式 大全 总结 参考整理了一些javascript正则表达式 目的一:自我复习归纳总结 目的二:共享方便大家搜索 微信:wixf150 验证数字:^[0-9]*$ 验证n ...