<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="">
</head>
<body>
<script type="text/javascript">
// 函数声明式 函数表达式
// 关于函数声明具有 函数声明提升
function functionName(arg0, arg1, arg2) {
// 函数体
}
sayHi()
function sayHi() {
alert("hi")
}
// 函数表达式 这种函数叫做 匿名函数 也叫做 拉姆达函数
var functionName = function(arg0, arg1, arg2) {
// 函数体
}
sayHi() //错误 函数不存在
var sayHi = function() {
alert("hi")
}
// 函数声明 和函数表达式 最大的区别是 函数提升
// 不能这样做
if (condition) {
function sayHi() {
alert("hi")
}
} else {
function sayHi() {
alert("Yo!")
}
}
// 上面代码 浏览器解析出来的最终结果是 function sayHi() {alert("Yo!")}
// 关键是。函数和变量的预解析
// 可以这样做
var sayHi
if (condition) {
sayHi = function() {
alert("hi")
}
} else {
sayHi = function() {
alert("Yo!")
}
}
function createComparisonFunction(propertyName) {
return function(object1, object2) {
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if (value1 < value2) {
return -1
} else if (value1 > value2) {
return 1
} else {
return 0
}
}
}
// 递归 递归函数就是 在一个函数名 通过名字调用自身的情况下构成
function factorial(num) {
if (num < 1) {
return 1
} else {
return num * factorial(num - 1)
}
}
var anotherFactorial = factorial
factorial = null
alert(anotherFactorial(4)) //出错
// 解决方案 arguments.callee 是一个指向 正在执行的函数的指针
function factorial(num) {
if (num < 1) {
return 1
} else {
return num * arguments.callee(num - 1)
}
}
// 如果在严格模式下 可以用命名函数表达式 达到相同的效果
var factorial = (function f(num) {
if (num < 1) {
return 1
} else {
return num * f(num - 1)
}
})
// 7.2 闭包 闭包是指定有权访问另一个函数作用域中变量的函数 闭包常见方式。在一个函数内部创建另一个函数
function createComparisonFunction(propertyName) {
return function(object1, object2) {
var value1 = object1[propertyName]; // ...
var value2 = object2[propertyName] // ...
if (value1 < value2) {
return -1
} else(value1 > value2) {
return 1
} else {
return 0
}
}
}
// 这里的作用域链 和 原型链 区分一下
// 当一个函数 被调用的时候 会创建 execution content (执行环境) 及其相应的作用域链
// 使用 arguments 和其它命名参数值来处初始化函数的活动对象 (activation object) 在作用域链 外部函数对象处于第二位 外部函数的外部函数对象 处于第三位 一次类推 直至 作用链条终点的全局执行环境
function compare(value1, value2) {
if (value1 < value2) {
return -1
} else if (value1 > value2) {
return 1
} else {
return 0
}
}
var result = compare(5, 10)
// 7.2.1 闭包与变量
function createFunctions() {
var result = new Array()
for (var i = 0; i < 10; i++) {
result[i] = function() {
return i
}
}
return result
}
createFunctions()
// 匿名函数强行闭包
function createFunctions() {
var result = new Array()
for (var i = 0; i < 10; i++) {
result[i] = function(num) {
return function() {
return num
}
}(i)
}
return result
}
// 7.22 关于this 的对象。this 对象 是在运行基本函数的执行环境中绑定的
// this 在全局函数函数中 是window 而函数作为某个对象的方法调用时 this 就是那个对象
// 匿名函数的执行环境 具有全局性
var name = "The Window"
var object = {
name: "My Object",
getNmaeFunc: function() {
return function() {
return this.name
}
}
}
console.log(object.getNmaeFunc()()) // "The Window" (在非严格模式下)
// 闭包和匿名函数 唯一的区别就是 函数有没有 有权访问另一个函数作用域中的变量
var name = "The Window"
var object = {
name: "My Object",
getNameFunc: function() {
var that = this
return function() {
return that.name
}
}
}
console.log(object.getNmaeFunc()())
// 在通过 call 后者apply 改变函数执行环境的情况下 this 就会指向其它对象
var name = "The Window"
var object = {
name: "My Object",
getName: function() {
return this.name
}
}
object.getName() // My Object
(object.getName)() // My Object
(object.getName = object.getName)() // The Window
// 内存泄漏
function assignHandler() {
var element = document.getElementbyId("someElement")
element.onclick = function() {
alert(element.id)
}
}
// 内存正常收回
function assignHandler() {
var element = document.getElementbyId("someElement")
var id = element.id
element.onclick = function() {
alert(id)
}
element.null
}
// 模仿块计作用域
function outputNumbers(count) {
for (var i = 0; i < count; i++) {
alert(i)
}
alert(i)
}
// 匿名函数 块级作用域
(function() {
// 这里是块级作用域
})()
var someFuncton = function() {
// 这里是块级作用域
}
someFuncton()
function() {
// 这里是块级作用域 也叫做 私有作用域
}() // 会报错 functoin 关键字作为函数声明的开始 函数声明后不能跟圆括号
(function() {
})()
function outputNumbers(count) {
(function() {
for (var i = 0; i < count; i++) {
alert(i)
}
})()
alert(i) // 这里会报错
}
// 在很多开发人员 共同参与的大型项目 过多的全局变量和函数 容易导致 命名冲突 而通过创建私有作用域
(function() {
var now = new Date()
if (new.getMonth() == 0 && now.getDate() == 1) {
alert("Happy new Year")
}
})()
// 其中now 是匿名函数中的局部变量
// 7.4 私有变量 任何函数中定义的变量, 都可以认为是私有变量 私有变量 包括 函数参数 局部变量 和在函数内部定义的其它函数
function add(num1, num2) {
var sum = num1 + num2;
return sum
}
// 我们把 有权访问私有变量和私有函数的 公有方法 称为特权方法 创建特权方法 有两种 第一种 构造函数
function MyObject() {
// 私有变量 和私有函数
var privateVariable = 10
function privateFunction() {
return false
}
this.publicMethod = function() {
privateVariable++
console.log(privateVariable)
return privateFunction();
}
}
var instance = new MyObject()
// 利用私有和特权成员 可以隐藏哪些不应该被直接修改的数据
function Person(name) {
this.getName = function() {
return name
}
this.setName = function(value) {
name = value
}
}
var person1 = new Person("Nicholas");
person1.getName()
person1.setName("Greg")
person1.getName()
// 构造函数 每个实例都会创建同样的一组方法
// 7.4.1 静态私有变量
(function() {
// 私有变量和私有函数
var privateVariable = 10;
function privateFunction() {
return false
}
// 构造函数
MyObject = function() {
};
// 公有/ 特权方法
MyObject.prototype.publicMethod = function() {
privateVariable++
return privateFunction();
}
})()
// 利用原型 实现所有的方法都是共享的
(function() {
var name = '';
Person = function(value) {
name = value
}
Person.prototype.getName = function() {
return name
}
Person.prototype.setName = function(value) {
name = value
}
})()
var person1 = new Person("Nicholas");
person1.getName()
person1.setName("Greg")
person1.getName()
var person2 = new Person("Michael");
person1.getName()
person2.getName()
// person2.__proto__ === person2.__proto__
// 多查找作用域链一个层次 就会在一定程度上影响查找的速度 这正是使用闭包和私有变量的一个明显不足之处
// 模块模式 7.4.2
// 模块模式 就是为单例 创建私有变量 和特权方法 singleton (只有一个对象的实例)
var singleton = {
name: value,
method: function() {
// 这里是方法的代码
}
}
var singleton = function() {
// 私有变量 和私有方法
var privateVariable = 10;
function privateFunction() {
return false;
}
// 特权 公有方法和属性
return {
publicProperty: true,
publicMethod: function() {
privateVariable++;
return privateFunction()
}
}
}
var instance = new singleton()
// 例子
var application = function() {
// 私有变量 和函数
var components = new Array()
// 初始化
// components.push(new BaseComponent())
return {
getComponentCount: function() {
return components.length
},
registerComponent: function(component) {
if (typeof component == "object") {
components.push(component)
}
}
}
}
// 模块模式 7.4.3 增强的那么模块模式
var singletion = function() {
// 私有变量 和私有方法
var privateVariable = 10;
function privateFunction() {
return false;
}
// 创建对象
CustomType = function() {}
var object = new CustomType()
// 添加特权 /公有属性和方法
object.publicProperty = true;
object.publicMethod = function() {
privateVariable++;
return privateFunction()
}
return object;
}()
//
var application = function() {
// 私有变量 和私有方法
var components = new Array()
// 初始化
var BaseComponent = function() {
}
components.push(new BaseComponent())
// 创建一个局部 appliction 的副本
var app = new BaseComponent()
app.getComponentCount = function() {
return components.length
}
app.registerComponent = function(component) {
if (typeof component == "object") {
components.push(component)
}
}
return app
}()
</script>
</body>
</html>
函数表达式
最新推荐文章于 2023-06-03 16:37:09 发布