《JavaScript核心技术开发解密》读书笔记(三)

《JavaScript核心技术开发解密》读书笔记(一)
《JavaScript核心技术开发解密》读书笔记(二)
《JavaScript核心技术开发解密》读书笔记(三)
《JavaScript核心技术开发解密》读书笔记(四)
《JavaScript核心技术开发解密》读书笔记(五)
下面是第八章–函数与函数式编程

函数
函数形式大概有四种,分别是函数声明、函数表达式、匿名函数与自执行函数

1、函数声明
函数声明是指利用关键字 function 来声明一个函数。在变量对象的创建过程中,function声明的函数比var声明的变量有更加优先的执行顺序,即函数声明提前(提升)。因此在同一执行上下文中,无论在什么地方声明了函数,都可以直接使用。

function fn() {
	console.log('function') ;
}

2、函数表达式
函数表达式是将一个函数体赋值给一个变量的过程。

var fn = function () {}

上面代码的执行步骤如下:
其中,把var fn = undefined会因为变量对象的原因而提前执行,即变量提升,因此使用函数表达式时,要注意代码的先后顺序。

var fn = undefined;
fn = function () {}

3、匿名函数
匿名函数即没有名字的函数,一般会作为一个参数或者一个返回值来使用,通常不使用变量来保存它的引用。
常见的匿名函数使用和场景:

// 1.setTimeout中的参数
var timer = setTimeout(function () {
	console.log('timer')
}, 1000)
// 2.数组方法中的参数
var arr = [1,2,3];
var arr2 =  arr.map(function (item) {
	return item + 1;
})
// 3.匿名函数作为一个返回值
function add() {
	var a = 10;
	return function () {
		return a + 10
	}
}
add()();

4、自执行函数
函数会产生独立的作用域,因此可以利用自执行函数来模拟块级作用域。

(function () {
	// 一些逻辑
})()

当我们使用自执行函数创建一个模块时,也就意味着,外界已经无法访问该模块内部的任何属性与方法了。好在有闭包,作为模块之间能相互交流的桥梁,让模块能够在我们的控制之下,选择性地对外开发属性与方法。

(function() {
	// 私有变量
	var age = 22;

	// 私有方法
	function getAge() {
		return age;
	}
	// 将引用保存在外部执行环珑的变量中,这是一种简单的对外开发方法的方式
	window.getAge = getAge;
})();

函数式编程
函数式编程,即函数封装

纯函数
相同的输入总会得到相同的输出,并且不会产生副作用的函数,就是纯函数。

var source = [1, 2, 3, 4, 5];
source.slice(1, 3); // 纯函数返回[2, 3] , source 不变
source.splice(1, 3); // 不纯 函数返 回[2, 3, 4] , source被改变了
source.pop(); // 不纯
source.push(6); // 不纯的
source.shift(); // 不纯的
source.unshift(1); // 不纯的
source.reverse(); // 不纯的
 //不能短时间知道现在source 被改变成什么样子了,干脆重新约定 一下
source = [1, 2, 3, 4, 5];
source.concat([6, 7]); // 纯函数返回[1, 2, 3, 4, 5, 6, 7], source不变
source.join('-'); // 纯函数返回1-2-3-4-5, source不变

高阶函数
简单粗暴一点来理解,则凡是接收一个函数作为参数的函数,就是高阶函数。

模拟关键字new

// 将构造函数以参数的形式传入
function New(func) {
	// 声明一个中间对象,该对象为最终返回的实例
	var res = {};
	if (func.prototype !== null) {
		// 将实例的原型指向构造函数的原型
		res.__proto__ = func.prototype;
	}

	// ret 为构造函数的执行结果,这里通过apply,将构造函数内部的this指向修改为指向res,即为实例对象
	var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
    
    // 当在构造函数中明确指定了返回对象时,那么new的执行结果就是该返回对象
	if ((typeof ret === 'object' || typeof ret === 'function') && ret !== null) {
		return ret;
	}
	
	// 如果没有明确指定返回对象,则默认返回res,这个res就是实例对象
	return res;
}

实现数组的map方法

Array.prototype._map = function (fn, context) {
	// 首先定义一个数组来保存每一项的运算结果,最后返回
	var temp = [];
	if (typeof fn == 'function') {
		var k = 0;
		var len = this.length;
		for (; k < len; k++) {
			// 将每一项的运算操作丢进fn里,利用call方法指定fn的this指向与具体参数
			temp.push(fn.call(context, this[k], k, this));
		}
	} else {
		console.error('TypeError: '+ fn +'is not a function.');
	}

	// 返回每一项运算结果组成的新数组
	return temp;
}

柯里化
柯里化是指这样一个函数(假设叫作createCurry),它接收函数A作为参数徐,运行后能够返回一个新的函数,并且这个新的函数能够c处理函数A的剩余参数。

// arity 用来标记剩余参数的个数
//  args 用来收集参数
function createCurry(func, arity, args) {
	// 第一次执行时,并不会传入arity,而是直接获取func参数的个数func.length
	var arity = arity || func.length;

	//第一次执行也不会传入args,而是默认为空数组
	var args = args || [];
	
	var wrapper = function() {
		// 将wrapper中的参数收集到args中
		var _args = [].slice.call(arguments);
		[].push.apply(args, _args);

		// 如果参数个数小于最初的func.length,则递归调用,继续收集参数
		if (_args.length < arity) {
			arity -= _args.length;
			return createCurry(func, arity, args);
		}

		// 参数收集完毕,执行func
		return func.apply(func, args);
	}

	return wrapper;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript核心技术 简介: 《JavaScript核心技术》对于各种浏览器、浏览器版本、JavaScript版本、DOM版本的介绍,有助于我们理解所遇到的各种新旧代码,使我们能够对这些代码做出正确的取舍。《JavaScript核心技术》还提供了一些使用JavaScript的最佳实践。无论是新手还是老手,这些如何正确使用JavaScript的经验都能帮助他们养成良好的编程习惯。《JavaScript核心技术》还介绍了一些调试和开发JavaScript的工具,这些工具无疑能够提高我们的开发效率。 《JavaScript核心技术》最后对于Ajax和几个流行的JavaScript库的介绍,无疑会开阔我们在JavaScript使用上的思路。 《JavaScript核心技术》是一本真正意义上的“新书”,不仅介绍了最新的JavaScript知识和方向,还完全覆盖了当今Web开发中关于JavaScript的所有重要话题,它使用了大量实例代码,图文并茂地讲解了使用JavaScript的各个层次和领域的内容。它不是一本参考手册,但却是一本值得拥有的教程。 JavaScript核心技术 目录: 前言 第1章JavaScript初探 1.1规范和实现相互交织的历史 1.2跨浏览器的不兼容性和其他常见的JavaScript传说 1.3你能用JavaScript来做什么 1.4JavaScript初探:“HelloWorld!” 1.5JavaScript沙箱 1.6可访问性和JavaScript的最佳实践 第2章JavaScript数据类型与变量 2.1变量的标识 2.2作用域 2.3简单类型 2.4常量:有名称但不改变 2.5习题 第3章运算符和语句 3.1JavaScript语句的格式 3.2简单语句 3.3条件语句和程序流 3.4条件运算符 3.5逻辑运算符 3.6高级语句:循环语句 3.7习题 第4章JavaScript对象 4.1对象构造函数 4.2Number对象 4.3String对象 4.4正则表达式与RegExp 4.5有专门用途的对象:Date和Math 4.6JavaScript数组 4.7关联数组:不是数组的数组 4.8习题 第5章函数 5.1定义函数:细数所有方式 5.2回调函数 5.3函数和递归 5.4嵌套函数、函数闭包和内存泄漏 5.5作为对象的函数 5.6习题 第6章捕捉事件 6.1O级DOM上的事件句柄 6.22级DOM上的事件句柄 6.3产生事件 6.4习题 第7章表单与即时验证 7.1访问表单 7.2把事件附加在表单上:不同的方法 7.3选择列表 7.4单选按钮和复选框 7.5输入字段和JiT正则表达式 7.6习题 第8章沙箱及之上的cookie、连通性和隐私 第9章基础浏览器对象 第10章DOM:文档对象模型 第11章创建定制的JavaScript对象 第12章构建动态网页:在脚本中加入样式 第13章使用Ajax 第14章好消息:生动的程序库!令人惊异的Web服务!有趣的API! 附录习题答案

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值