JavaScript语法

JavaScript语法


1.基本概念
1.1 区分大小写
1.2 标识符按一下规则组合:
(1)第一个字符必须是一个字母、下划线(_)或一个美元符号($)
(2)其他字符可以是字母、下划线、美元符号或数字
1.3 严格模式:"use strict";
1.4 值类型:Undefined,Boolean,Number,String
1.5 引用类型:Null,Object
1.6 检测类型
(1)typeof操作符
字符串、数值、布尔值、undefined分别返回string、number、boolean、undefined。
对象和null则返回object。
例如:var s = "Today"; alert( typeof s); // string
(2)instanceof操作符
用于判断对象类型,例如:alert(colors instanceof Array); // 变量colors是Array吗?

2 执行环境及作用域
2.1 定义
执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。全局执行环境是最外围的一个执行环境,在Web浏览器中,全局执行环境被定义为window对象。当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。嵌套函数通过作用域链由里到外一层层搜索使用的变量和函数。
2.2 延迟作用域链
(1)try-catch语句的catch块
(2)with语句
2.3 没有块级作用域
注:
(1)由for语句创建的变量i即使在for循环执行结束后,也依旧会存在于循环外部的执行环境中。
(2)使用var声明的变量会自动被添加到最接近的环境中,而初始化变量没有使用var声明的,就会被添加到全局环境。


3 Object类型
3.1 创建Object对象
(1)使用new操作符
var person = new Object();
persion.name = "Tom";
persion.age = 30;
(2)使用对象字面量表示法
var persion = {
name : "Tom",
age : 30
}
或者
var persion = {};
persion.name = "Tom";
persion.age = 30;
3.2 创建Array对象
(1)使用Array构造函数
var colors = new Array();
var colors = new Array(20); // 长度为20的数组
var colors = new Array("red", "blue", "green");
(2)使用数组字面量表示法
var colors = ["red", "blue", "green"];
var colors = []; // 创建空数组


4 Function类型
4.1 函数实际上是对象。
函数名实际上是对象名,因此函数是没有重载的。
ECMAScript函数不介意传递的参数个数和类型,函数体内可以通过arguments对象访问参数数组。

4.2 创建Function
(1)函数声明
alert(sum(10, 10));
function sum(num1, num2){
return num1 + num2;
}
(2)函数表达式
alert(sum(10, 10));// 运行错误,sum未定义
var sum = function(num1, num2){
return num1 + num2;
};
注:在代码开始执行之前,解释器就已经通过一个名为函数声明提升的过程,读取并将函数声明添加到执行环境中,而函数表达式则只是变量声明。

4.3 因为函数名本身就是变量,所以函数也可以作为值来使用,譬如用于函数参数。


4.4 函数内部属性
(1)在函数内部,有两个特殊的对象:arguments和this。
注:在ECMAScript5页规范了另一个函数对象的属性:caller。这个属性保持调用当前函数的函数的引用。
arguments有一个callee属性,是一个指针,指向拥有这个arguments对象的函数。
this引用的是函数据以执行的环境对象——也就是函数对象本身,在全局环境this对象引用的就是window。
(2)每个函数都包含两个属性:length和prototype
length属性表示函数希望接收的命名参数的个数。
prototype属性是最耐人寻味。
(3)每个函数都包含两个非继承而来的方法:apply()和call()
这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
它们强大的地方是能够扩充函数赖以运行的作用域。
apply()方法和call()方法的作用相同,接收的第一个参数都是运行函数的作用域,区别是apply()接收的第二个参数是数组,而call()剩下的参数需要逐个列出来。
注:ECMAScript5还定义了一个方法:bind()。用这个方法创建一个函数实例,其this值会被绑定到传给bind()函数的值。
例子:
	window.color = "red";
	var o = { color : "blue" };
	funciton sayColor(){
		alert(this.color);
	}
	var objSayColor = sayColor.bind(o);
	
	sayColor(); // red
	sayColor.call(window); // red
	sayColor.call(o); // blue
	objSayColor(); // blue

4.5闭包
闭包是指有权访问另一个函数作用域中的变量的函数。
创建闭包的常见方式,就是在一个函数内部创建另一个函数。

例子:

	var name = "The window";
	var obj = {
		name : "My Object",
		getNameFunc : function(){
			return function(){
				return this.name;
			}
		}
	};
	var obj2 = {
		name : "My Object",
		getNameFunc : function(){
			var that = this;
			return function(){
			  return that.name;
			}
		}
	};
	alert(obj.getNameFunc()()); // The window
	alert(obj.getNameFunc().call(obj));// My Object
	alert(obj2.getNameFunc()()); // My Object

4.6模仿块级作用域
(1)用作块级作用域(通常称为私有作用域)的匿名函数语法如下:
(function(){
// 这里是块级作用域
})();
(2)私有变量
严格来讲,所有对象属性都是公有的。但有一个私有变量的概念:
任何在函数中定义的变量,都可以认为是私有变量,因为不能在函数外部访问这些变量。
我们把有权访问私有变量和私有函数的公有方法称为特权方法。
例子:
	function MyObject(){
		// 私有变量和函数
		var privateVariable = 10;
		function privateFunction(){
			return false;
		}
		// 特权方法
		this.publicMethod = function(){
			privateVariable++;
			return privateFunction();
		}
	}

5面向对象的程序设计
5.1属性类型
(1)数据属性
[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。这个属性默认值为ture。
[[Enumerable]]:表示能否通过for-in循环返回属性。这个属性默认值为ture。
[[Writable]]:表示能否修改属性的值。这个属性默认值为ture。
[[Value]]:包含这个属性的数据值。这个属性默认值为undefined。
例子:
	var person = { };
	object.defineProperty(persion, "name", {
		configurable : false,
		writable : false,
		value : "Tom"
	});
	alert(person.name); // Tom
	person.name = "Greg";
	alert(person.name); // Tom
	delete person.name;
	alert(person.name); // Tom

(2)访问器属性
[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。这个属性默认值为ture。
[[Enumerable]]:表示能否通过for-in循环返回属性。这个属性默认值为ture。
[[Get]]:在读取属性时调用的函数。默认值为undefined。
[[Set]]:在写入属性时调用的函数。默认值为undefined。
例子:
	var book = {
		_year : 2004,
		edition :1
	};
	Object.defineProperty(book, "year", {
		get : function(){
			return this._year;
		},
		set : function(newValue){
			if(newValue > 2004){
				this._year = newValue;
				this.edition += newValue - 2004;
			}
		}
	});
	book.year = 2005;
	alert(book.edition); // 2

5.2创建对象
(1)工厂模式
	function createPerson(name, age){
		var o = new Object();
		o.name = name;
		o.age = age;
		o.sayName = function(){
			alert(this.name);
		};
		return o;
	}
	var person1 = createPerson("Tom", 30);

(2)构造函数模式
	function Person(name, age){
		this.name = name;
		this.age = age;
		this.sayName = function(){
			alert(this.name);
		};
	}
	var person1 = new Person("Tom", 30);

(3)原型模式
	function Person(){
	}
	Person.prototype.name = "Tom";
	Person.prototype.age = 30;
	Person.prototype.sayName = function(){
		alert(this.name);
	};
	var person1 = new Person();
	person1.sayName(); // Tom
	var person2 = new Person();
	person2.sayName(); // Tom
	alert(person1.sayName == person1.sayName); // true
注:hasOwnProperty()方法可以坚持一个属性时存在于实例中还是原型中。
alert(person1.hasOwnProperty("name"); // false
person1.name = "Greg";
alert(person1.name); // Greg
alert(person1.hasOwnProperty("name"); // true

注:in操作符会在通过对象能够访问给定属性时返回true,无论该属性存在于实例中还是原型中。

alert("name " in person1); // true


(3)组合使用构造函数模式和原型模式
	function Person(name, age){
		this.name = name;
		this.age = age;
		this.friends = ["Shelby", "Court"];
	}
	Person.prototype = {
		constructo : Person,
		sayName : function(){
			alert(this.name);
		}
	};
	var person1 = new Person("Greg", 29);
	var person2 = new Person("Tom", 27);
	person1.friends.push("Van");
	alert(person1.friends); // Shelby, Court, Van
	alert(person2.friends); // Shelby, Court
	alert(person1.friends == person1.friends); // false
	alert(person1.sayName == person1.sayName); // true


5.3继承
所有的引用类型默认都继承了Object,而这个继承是通过原型链实现的。
(1)原型链
	function SuperType(){
		this.property = true;
	}
	SuperType.prototype.getSuperValue = function(){
		return this.property;
	};
	function SubType(){
		this.subproperty = false;
	}
	// 继承SuperType
	SubType.prototype = new SuperType();
	SubType.prototype.getSubValue = function(){
		return this.subproperty;
	};
	var instance = new SubType();
	alert(instance.getSuperValue()); // true
	alert(instance instanceof Object); // true
	alert(instance instanceof SuperType); // true
	alert(instance instanceof SubType); // true


(2)借用构造函数

	function SuperType(name){
		this.name = name;
		this.colors = ["red", "blue", "green"];
	}
	function SubType(){
		// 继承SuperType
		SuperType.call(this, "Tom");
		this.age = 29;
	}
	var instance1 = new SubType();
	instance1.colors.push("black"); 
	alert(instance1.colors); // red, blue, green, black
	var instance2 = new SubType();
	alert(instance2.colors); // red, blue, green


(3)组合继承
组合继承是JavaScript最常用的继承模式。它将原型链和借用构造函数的技术组合在一起。

	function SuperType(name){
		this.name = name;
		this.colors = ["red", "blue", "green"];
	}
	SuperType.prototype.sayName = function(){
		alert(this.name);
	};
	function SubType(name, age){
		// 继承属性
		SuperType.call(this, name);
		this.age = age;
	}
	// 继承方法
	SubType.prototype = new SuperType();
	SubType.prototype.constructor = SubType;
	SubType.prototype.sayAge = function(){
		alert(this.age);
	};
	var instance1 = new SubType("Greg", 29);
	instance1.colors.push("black"); 
	alert(instance1.colors); // red, blue, green, black
	instance1.sayName(); // Greg
	instance1.sayAge(); // 29
	
	var instance2 = new SubType("Tom", 30);
	alert(instance2.colors); // red, blue, green
	instance2.sayName(); // Tom
	instance2.sayAge(); // 30


(4)原型式继承
	function object(o){
		function F( ){ };
		F.prototype = o;
		return new F();
	}
	// 下面是实例
	var person = {
		name : "Nicholas",
		friends : ["Shelby", "Court"]
	}
	var anotherPerson = object(person);
	anotherPerson = "Greg";
	anotherPerson.friends.push("Van");
	
	var yetAnotherPerson = object(person);
	yetAnotherPerson.name = "Linda";
	anotherPerson.friends.push("Rob");
	
	alert(person.friends); // Shelby, Court, Van, Rob


(5)寄生式继承
寄生式继承是与原型式继承紧密相关的一种思路。
	function createAnother(original){
		var clone = object(original); // 通过调用函数创建一个新对象
		clone.sayHi = function(){ // 以某种方式来增强这个对象
			alert("Hi");
		};
		return clone; // 返回这个对象
	}
	// 下面是实例
	var person = {
		name : "Nicholas",
		friends : ["Shelby", "Court"]
	}
	var anotherPerson = createAnother(person);
	anotherPerson.sayHi(); // hi

(6)寄生组合式继承

	// 寄生式组合式继承的基本模式
	function inheritPrototype(subType, superType){
		var prototype = object(superType.prototype); // 创建对象
		prototype.constructor = subType; // 增强对象
		subType.prototype = prototype; // 指定对象
	}
	// 下面是实例
	function SuperType(name){
		this.name = name;
		this.colors = ["red", "blue", "green"];
	}
	SuperType.prototype.sayName = function(){
		alert(this.name);
	};
	function SubType(name, age){
		SuperType.call(this, name);
		this.age = age;
	}
	inheritPrototype(SubType, SuperType);
	SubType.prototype.sayAge = function(){
		alert(this.age);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值