<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script type="text/javascript">
var array=[1,2,3,4,5,6];
var arr=array.map(function(item){
return item*2;
});
alert(arr[0]);// 2
------------------------------------------------
/////变量的作用域
var variable="out";
function func()
{
variable="in";
alert(variable);
}
func(); // 打印"in"
alert(variable); // 打印"in"
------------------------------------------------
var object={
field:"self",
printInfo:function(){
alert(this.field);
}
}
alert(object.field); //"self"
object.printInfo(); // "self"
for(var key in object){
alert(key+" : "+object[key]);
}
------------------------------------------------
///JavaScript对象
function Base(name) {
this.name = name;
this.getName = function () {
return this.name;
}
}
function Child(id) {
this.id = id;
this.getId = function () {
return this.id;
}
}
//将Child原型指向一个新的base对象
Child.prototype = new Base("base");
//实例化一个Child对象
var c1 = new Child("child");
//调用c1本身的getId方法
alert(c1.getId()); //child
//由于c1从原型链上“继承”到了getName方法,因此可以访问
alert(c1.getName()); //base
//////注解:由于遍历原型链时是由下而上的,所以最先遇到的属性值最先返回
function Person(name, age) {
this.name = name;
this.age = age;
this.getName = function () {
return this.name;
}
this.getAge = function () {
return this.age;
}
}
var tom = new Person("Tom", 30);
var jerry = new Person("jerry", 40);
////注解:通过原型链,可以实现继承/重载等面向对象的js代码。当然这个机制并非基于类,而是基于原型
------------------------------------------------
//定义个“类”,Address
function Address(street, xno) {
this.street = street || "黄泉路";
this.xno = xno || 135;
this.toString = function () {
return "street:" + this.street + ",No:" + this.xno;
}
}
//定义另外一个“类”,Person
function Person(name,age,addr){
this.name = name || "未知";
this.age = age;
this.addr = addr || new Address(null, null);
this.getName = function () {
return this.name;
};
this.getAge = function () {
return this.age;
};
this.getAddr = function () {
return this.addr.toString();
};
}
//通过new 操作符来创建两个对象,注意,这个两个对象是相互独立的实体
var jack = new Person("jack", 26, new Address("青海路", 123));
var abruzzi = new Person("abruzzi", 26);
//查看结果
alert(jack.getName()); //jack
alert(jack.getAge()); //26
alert(jack.getAddr()); //street:青海路,No:123
alert(abruzzi.getName()); //abruzzi
alert(abruzzi.getAge()); //26
alert(abruzzi.getAddr()); //street:黄泉路,No:135
------------------------------------------------
////函数作用域
var str = "global";
function scopeTest() {
alert(str);
var str = "local";
alert(str);
}
scopeTest();
//运行结果 undefined local
///注解:因为在函数scopeTest的定义中,预先访问了未声明的变量str,然后才对str变量进行初始化,所以第一个alert会返回undefined错误。
///那为什么函数这个时候不会去访问外部的str变量呢?
///这是因为在词法分析结束后,构造作用域的时候会将函数内定义的var变量放入该链,因此str在整个函数内部是可见的(从函数体的第一行到最后一行),
///由于str变量本身是未定义的,程序顺序执行,到第一行就会返回为定义,第二行为str赋值
------------------------------------------------
/////闭包
///由于在javaScript中,函数是对象,对象是属性集合,而属性的值有可以是对象,则在函数内定义函数成为理所当然,如果在函数func内部声明函数inner,然后在函数外调用inner,这个过程即产生闭包。
var outter = [];
function clouseTest() {
var array = ["one", "two", "three", "four"];
for (var i = 0; i < array.length; i++) {
var x = {};
x.no = i;
x.text = array[i];
x.invoke = function () {
alert(i);
}
outter.push(x);
}
}
//调用
clouseTest();
outter[0].invoke();
outter[1].invoke();
outter[2].invoke();
outter[3].invoke();
///运行结果是 4 4 4 4 为什么不是0 1 2 3呢?
//因为每次在迭代的时候,语句x.invoke=function(){alert(i);}并没有被执行,只是构建了一个函数体为“alert(i);”的函数对象而已。
//如果每次迭代的时候语句x.invoke=function(){alert(i);}执行的话,则调用clouseTest()的时候则就会弹出对话框了,事实上却没有弹,证明没有执行
//如何解决呢?
var outter = [];
function clouseTest2() {
var array = ["one", "two", "three", "four"];
for (var i = 0; i < array.length; i++) {
var x = {};
x.no = i;
x.text = array[i];
x.invoke = function (no) {
alert(no);
}(i);//调用
outter.push(x);
}
}
//调用
clouseTest2();
------------------------------------------------
///封装
var person = function () {
//变量的作用域为函数内部,外部无法访问
var name = "张飞";
return {
getName: function () { return name; },
setName: function (newName) { name = newName; }
}
}();
alert(person.name);//直接访问,结果为undefined
alert(person.getName()); //张飞
person.setName("关羽");
alert(person.getName()); //关羽
function Person() {
var name = "张飞";
return {
getName: function () { return name; },
setName: function (newName) { name = newName; }
}
};
var john = new Person();
alert(john.getName()); //张飞
john.setName("john");
alert(john.getName()); // john
////在不同的Javascript解释器实现中,由于解释器本身的缺陷,使用闭包可能造成内存泄露(严重影响用户体验)
///如:对象A引用B,B引用C,而C又引用A
------------------------------------------------
///【面向对象的JavaScript】
//原型继承:js中的继承可以通过原型链来实现,调用对象上的一个方法,由于方法在javascript对象中是对另一个函数对象的引用,因此解释器会在对象中查找该属性,
//如果没有找到,则在其内部对象prototype对象上搜索。由于prototype对象与对象本身的结构是一样的,因此这个过程会一直回溯到发现该属性,否则,报错
function Base() {
this.baseFunc = function () { alert("基础行为");}
}
function Middle() {
this.middleFunc = function () { alert("中间行为");}
}
Middle.prototype = new Base();
function Final() {
this.finalFunc = function () { alert("最终行为");}
}
Final.prototype = new Middle();
function Test() {
var obj = new Final();
obj.baseFunc();
obj.middleFunc();
obj.finalFunc();
}
Test();///// 基础行为 中间行为 最终行为
// 原型链示意图 见图 P76
///new 操作符
function Shape(type) {
this.type = type || "rect";
this.calc = function () { return "calc," + this.type;}
}
var triangle = new Shape("triangle");
alert(triangle.calc());
var circle = new Shape("circle");
alert(circle.calc());
////注解:Javascript和其他面向对象的new操作符不一样,triangle,circle可能在Java中是Shape对应的具体对象,但是在js中并非如此(new比较特殊)
////首先,创建一个空对象,然后用函数apply方法,将这个空对象传入作为apply的第一个参数以及上下文参数,这样的函数内部的this将会被这个空的对象所替代。
var triangle = new Shape("triangle");
///相当于下面的代码
var triangle = {};
Shape.apply(triangle, ["triangle"]);
------------------------------------------------
///柯里化
//柯里化就是余下将函数的某些参数传入,得到一个简单的函数,但是预先传入的参数被保存在闭包中,因此会有一些奇特的特性
var addr = function (num) {
return function (y) { return num + y;}
}
var inc = addr(1);
var dec = addr(-1);
alert(inc(99)); //100
alert(dec(101)); // 100
alert(addr(100)(2)); // 102
alert(addr(2)(100)); // 102
------------------------------------------------
//开发智力(坑爹)
//函数的不动点
function fixedPoint(Func, first) {
var tolerance = 0.00001;
function closeEnough(x, y) {
return Math.abs(x - y) < tolerance;
};
function Try(guess) {
var next = Func(guess);
//alert(next+" "+ guess);
if (closeEnough(guess, next)) {
return next;//返回小的
}
else {
return Try(first);//递归调用
}
};
return Try(first);
}
//数层嵌套函数
function sqrt(x) {
var Func = function (y) {
var div = function (a, b) { return (a + b) / 2; }
return div(y, x / y);
}
return fixedPoint(Func, 1.0);
}
alert(sqrt(100));
------------------------------------------------///原型链:由于原型对象本身也是对象,它也有自己的原型,而他自己的原型对象又可以有自己的原型,这样就组成了一条链,这个链就是原型链
///Javascript引擎在访问对象的属性时,如果在对象本身中没有找到,则会去原型链中查找,如果找到,直接返回值,如果整个链都遍历且没有找到属性,则返回undefined。原型链一般是实现为一个链表,这样就可以按照一定的顺序来查找
var base = {
name: "base",
getInfo: function () {
return this.name;
}
}
var ext1 = {
id: 0,
__proto__:base
}
var ext2 = {
id: 9,
__proto__:base
}
alert(ext1.id); //0
alert(ext1.getInfo()); //base
alert(ext2.id); //9
alert(ext2.getInfo()); // base
//原型链图 见P105
var base = { ///(原型对象)
name: "base",
getInfo: function () { return this.id + " : " + this.name;}
};
var ext1 = { ///(原始对象)
id: 0,
__proto__:base
};
alert(ext1.getInfo()); // 0 : base
///注解:getInfo函数中的this表示原始的对象,并非原型对象,上例中的id属性来自于ext1对象,而name来自base对象
///如果没有显示的声明自己的”__proto__“属性,这个值默认的设置为Object.prototype,而Object.prototype的“__proto__”属性值为“null”,标志着原型链的终结
------------------------------------------------
///执行期上下文:按照ECMAScript的规范,一共有三种类型的代码,全局代码、函数代码、以及eval代码
///this上下文:ECMAScript的规范中对this的定义为:this是一个特殊的对象,与执行期上下文相关,因此可以称为上下文对象。
///this是执行期上下文对象的一个属性(执行期上下文对象包括变量对象、作用域链以及this)。执行期上下文对象有三类,当进入不同的上下文时,this的值会确定下来,并且this的值不能更改。
///在执行全局代码时,控制流会进入全局执行期上下文,而在执行函数时,又会有函数执行期上下文
var global = this;
var tom = {
name: "Tom",
home: "desine",
getInfo: function () {
alert(this.name + ", from " + this.home);
}
};
tom.getInfo(); // Tom,from desine
var jerry = {
name: "Jerry",
getInfo:tom.getInfo
};
jerry.getInfo(); // Jerry,from undefined
global.getInfo = tom.getInfo;
global.getInfo(); // ,from undefined
</script>
</head>
<body>
</body>
</html>
来源:https://www.cnblogs.com/wang0379/p/3940046.html