面向对象的JavaScript-1.语言特征
来源:互联网 发布:js数组添加值 编辑:程序博客网 时间:2024/05/20 23:36
JavaScript语言最重要的几个部分:
* 引用(reference)
* 作用域(scope)
* 闭包(closure)
* 上下文(context)
1 引用
“引用”是一个指向对象实际位置的指针。
但是有一个前提:实际的对象肯定不会是引用。字符串永远是字符串,数组永远是数组。不过多个变量却能指向同一对象。
此外,对象可以包含一系列属性(property),这些属性也都不过是其他对象(字符串、数字、数组等待)的引用。如果多个变量指向同一个对象,那该对象的类型一改变,所有这些变量也会跟着响应改变。
多个变量引用同一个对象的例子
// 创建obj空对象var obj = {};// objRef 是另一个对象的引用var objRef = obj;// 修改原对象的一个属性obj.oneProperty = true;// 这个修改在两个变量中都反应出来了,因为他们引用的是同一个对象alert(obj.oneProperty === objRef.oneProperty) // true
自修改对象在JavaScript中很少见。
自修改对象的例子
var items = ['one', 'two', 'three']// 创建一个数组的引用var itemsRef = items;// 给原数组添加一个元素items.push('four');alert(items === itemsRef) // true
必须要记住的是,引用指向的只能是具体的对象,而不是另一个引用。JavaScript里的结果是沿着引用链一直上溯到原来那个对象。
修改对象的引用,同时保持完整性的例子
var items = ['one', 'two', 'three']// 将 itemsRef 置为 items 的引用var itemsRef = items;// 将items置为一个新的对象items = ['new', 'array']alert(items != itemsRef) // true
实际对象已经改变了,但原来指向它的引用仍然指向旧的对象。
修改对象而生成新对象例子
var item = 'test';// itemsRef 指向同一个字符串对象var itemRef = item;// 将新文本接在这个字符串后面// 注意:这会创建一个新对象,而非修改原对象item += 'ing';// item 和 itemsRef 的值不相等了,因为系的字符串对象已被创建alert(item != itemRef) // true
2 函数重载和类型检查
函数重载必须依赖两件事情:
1. 判断传入参数数量的能力
2. 判断传入参数类型的能力
参数数量
JavaScript的每个函数都带有一个仅在这个函数范围内作用的变量称为参数(argument),它是一个包含所有传给函数的参数的伪数组(pseudo-array),所以它并非真正意义的数组(也就是说你不能修改它,也不能用push()来添加新元素),但可以访问其中的元素,它也具有.length属性。
JavaScript中函数重载的两个例子
function sendMessage(msg, obj){ if ( arguments.length == 2 ) { // 给对象发送消息 obj.handleMsg(msg); } else { alert(msg); }}sendMessage ('hello world');// 传入对象,负责用另一套办法显式信息sendMessage('how are you', { handleMsg: function (msg) { alert('This is a custom message: ' + msg) }})
// 一个接受任意数量参数并将其转化为数组的函数function makeArray () { var arr = []; for (var i=0; i< arguments.length; i++) { arr.push(arguments[i]) } return arr;}console.log(makeArray(1,2,3,4,5)) // [1, 2, 3, 4, 5]
如果没有提供参数,它的类型必为undefined.
显示错误信息和默认信息的例子
function displayerror (msg) { if ( typeof msg == 'undefined') { msg = 'An error occurred.'; } alert(msg)}displayerror ()
类型检查
typeof 是类型检查。既然JavaScript是动态类型的语言,有许多可以检查变量的类型。
1. 第一种使用typeof操作符
此方法只提供了一个字符串名称,用于表达变量的类型。
当变量不是object或array类型时,都能检测。但是无法区分Object和Array,它们都是返回object。
var obj={}var arr = [1,2,3,4]console.log(typeof obj) // objectconsole.log(typeof arr) // object
- 第二种检查对象类型的方法,需要引用所有JavaScript对象都带有的一个属性,称为构造函数。这一属性引用的是原本用来构造该对象的那个函数
使用构造函数属性来判断对象的类型的例子
var obj = {an: 'object'}var arr = ['an', 'array']var fn = function(){}var str = 'a string'var num = 55var boo = truefunction User() {}var newFn = new User()console.log(typeof(obj) + " : " + obj.constructor)// object : function Object() { [native code] }console.log(obj.constructor == Object) // trueconsole.log(typeof(arr) + " : " + arr.constructor)// object : function Array() { [native code] }console.log(arr.constructor == Array) // trueconsole.log(typeof(fn) + " : " + fn.constructor)// function : function Function() { [native code] }console.log(fn.constructor == Function) // trueconsole.log(typeof(num) + " : " + num.constructor)// number : function Number() { [native code] }console.log(num.constructor == Number) // trueconsole.log(typeof(boo) + " : " + boo.constructor)// boolean : function Boolean() { [native code] }console.log(boo.constructor == Boolean) // trueconsole.log(typeof(newFn) + " : " + newFn.constructor)// object : function User() {// this.user = 'people'// }console.log(newFn.constructor == User) // true
3 作用域
在JavaScript里,作用域是由函数划分的,而不是由块划分的(如while,if 和for语句中间)。导致的结果是某些代码不好理解
var foo = 'test'if (true) { var foo = 'new test'}function test (){ var foo = 'old test' console.log(foo == 'old test') // true}test()console.log(foo == 'new test') // true
可见函数是有作用域的
JavaScript中全局作用域和window对象的例子
// 一个全局作用域下的变量,存储了字符串‘test'var foo = 'test'// 全局变量和window对象的foo属性是一致的console.log(window.foo == foo) // true
如果变量没有显式定义,它就是全局定义的。
function test (){ foo = 'new test'}test()console.log(foo == 'new test') // trueconsole.log(window.foo == 'new test') // true
4 闭包
闭包(closure)意味着内层的函数可以引用存在于包围它的函数内的变量,即使外层函数的执行已经终止。
闭包的例子
var obj = document.getElementById('main')obj.style.border = '1px solid red'// 初始化一个在1秒后执行的函数setTimeout(function(){ // 引用了全局变量obj obj.style.display = 'none'},1000)function delayedAlert(msg, time){ setTimeout(function(){ // 它将使用包含本函数的外围函数传入的msg变量 alert(msg) },time)}delayedAlert('welcome' , 2000)
闭包的额外作用。在函数式程序语言里,有一种称为Curry化的技术。
Curry化是一种通过把多个参数填充到函数体中,实现将函数转化为一个新的经过简化的函数的技术。
用闭包实现的函数Curry化的例子
// 数字求和函数的函数生成器function addGenerator (num) { // 返回一个简单的函数,求两个数字的和,其中第一个数字来自生成器 return function(toAdd) { return num + toAdd }}// addFive 现在包含一个接受单一参数的函数,这个函数能求得5加上该函数的和var addFive = addGenerator(5)// 传入参数求和console.log(addFive(4)) // 9
闭包的另一种使用方式:自执行的匿名函数。
自执行匿名函数可以把所有属于全局的变量都隐藏起来
使用匿名函数来隐藏全局作用域变量的例子
(function(){ var msg = 'Thanks for visiting' window.onload = function(){ alert(msg) }})()
在for循环中使用闭包,利用闭包来引用循环的计数器
var obj = document.getElementById('main')var items = ['click', 'keypress']// 使用一个自执行的匿名函数来激发出作用域for (var i = 0; i< items.length; i++) { (function(){ // 记住在这个作用域内的值 var item = items[i] 将一个函数绑定到该元素 obj['on'+item] = function() { // item 引用本for循环上下文所属作用域中的一个父变量 alert('Thanks for your ' + item) } })()}
5 上下文对象
上下文对象是通过this变量体现的,这个变量永远指向当前代码所处的对象中。即使在全局上下文中,this变量指向window对象。
在上下文对象内使用函数并将其上下文切换为另一个变量的例子
var obj = { yes: function () { // this == obj this.val = true }, no: function () { this.val = false }}// obj对象没有val属性console.log(obj.val == null) // true// 指向yes函数后,将val属性与obj对象关联起来obj.yes()console.log(obj.val == true) // true// 把window.no 指向obj.no并执行var no = obj.nono()// obj对象的val不变console.log(obj.val == true) // true// window的val属性被更新了console.log(val == false) // true
把obj.no变量的上下文切换为window变量时,代码变得不好理解
JavaScript提供了一套方法来让这一过程变得更好理解和实现
修改函数上下文对象的例子
<div id="main" style="width:100px; height:100px"></div><script>function changeBackgroud (color) { this.style.background = color}// 在window对象中调用次函数会失败,因为window对象没有style属性// changeBackgroud('red')var main = document.getElementById('main')// changeBackgroud函数虽然在全局作用域下执行,但是把this指向了main// 使用call方法将它的颜色置为黑色。call方法将上下文对象设置为第一个参数,并将其他参数作为原函数的参数changeBackgroud.call(main,'black');// 设置body元素颜色的函数function setBodyColor () { // apply 方法将上下文对象设置为第一个参数制定的body元素,第二个参数是传给函数的所有参数的数组 changeBackgroud.apply(document.body, arguments)}setBodyColor('red')</script>
原文来自精通JavaScript和Pro JavaScript Techniques
- 面向对象的JavaScript-1.语言特征
- javascript面向对象——语言特征
- javascript面向对象特征
- JavaScript面向对象的三大特征
- 面向对象设计语言的显著特征
- 面向对象语言的三大特征
- 面向对象的Javascript语言
- 面向对象的特征
- 面向对象的特征
- 面向对象的特征
- 面向对象的特征
- 面向对象的特征
- 面向对象的特征
- 面向对象的特征
- 面向对象的特征
- 面向对象的特征
- 面向对象的特征
- 面向对象的特征
- java字节流边读边写
- 什么是框架?
- Unable to start adb server: error: protocol fault (couldn't read status): Connection reset by peer
- 将博客搬至CSDN
- 【R语言 可视化】R语言 ggplot2 一张图画多个饼
- 面向对象的JavaScript-1.语言特征
- 根据时间生成10位唯一性编码(最少9位)
- (HashMap,SparseArray,ArrayMap)
- Spark调优之Shuffle调优
- 【工具】Source Insight常用设置
- 城市选择插件
- python处理进制的转换
- Linux学习篇之---Ubuntu 14.04 重启后DNS配置丢失问题的解决方案,---ubuntu14.04
- A20简易Makefile解析