本文主要是介绍6.22 js学习笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
作用域
JavaScript 作用域
在 JavaScript 中, 对象和函数同样也是变量。
在 JavaScript 中, 作用域为可访问变量,对象,函数的集合。
JavaScript 函数作用域: 作用域在函数内修改。
JavaScript 局部作用域
变量在函数内声明,变量为局部作用域。
局部变量:只能在函数内部访问。
// 此处不能调用 carName 变量
function myFunction() {var carName = "Volvo";// 函数内可调用 carName 变量
}
因为局部变量只作用于函数内,所以不同的函数可以使用相同名称的变量。
局部变量在函数开始执行时创建,函数执行完后局部变量会自动销毁。
JavaScript 全局变量
变量在函数外定义,即为全局变量。
全局变量有 全局作用域: 网页中所有脚本和函数均可使用。
var carName = " Volvo";// 此处可调用 carName 变量
function myFunction() {// 函数内可调用 carName 变量
}
如果变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量。
以下实例中 carName 在函数内,但是为全局变量。
// 此处可调用 carName 变量function myFunction() {carName = "Volvo";// 此处可调用 carName 变量
}
JavaScript 变量生命周期
JavaScript 变量生命周期在它声明时初始化。
局部变量在函数执行完毕后销毁。
全局变量在页面关闭后销毁。
函数参数
函数参数只在函数内起作用,是局部变量。
HTML 中的全局变量
在 HTML 中, 全局变量是 window 对象: 所有数据变量都属于 window 对象。
//此处可使用 window.carNamefunction myFunction() {carName = "Volvo";
}
小结:
局部变量:在函数中通过var声明的变量。全局变量:在函数外通过var声明的变量。没有声明就使用的变量,默认为全局变量,不论这个变量在哪被使用。
闭包
闭包是一种保护私有变量的机制,在函数执行时形成私有的作用域,保护里面的私有变量不受外界干扰。
直观的说就是形成一个不销毁的栈环境。
js代码app1:
(function () {var n = "ime";function People(name) {this._name = name;}People.prototype.say=function () {alert("hello"+this._name+n);}//say 为方法window.People =People;
}()) ;//n 只能在闭包里访问(function () {function Student(name) {this._name = name;}Student.prototype =new People();// 继承Peoplevar superSay = Student.prototype.say;Student.prototype.say = function () {superSay().call(this);alert("s-hello"+this._name+n);} //子类window.Student =Student;
}());
var s = new Student("iwen");
s.say();
js代码app2:
(function () {var n="ime";function Person(name) {var _this={};_this._name= name;_this.sayHello = function () {alert("hello"+_this._name+n);};return _this;}window.Person = Person; //开个窗口}());
function Teacher(name) {var _this= Person(name);var superSay= _this.sayHello;_this.sayHello=function () {superSay.call(_this);alert("thello"+_this._name);};return _this;
}
var t=Teacher("iwen");
t.sayHello();
效果图
实例1:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<div id="1">1</div>
<div id="2">2</div>
<div id="3">3</div><script type="text/javascript">var i;for(i=1;i<=3;i++){var ele = document.getElementById(i);ele.onclick=(function (id) {return function () {alert(id);}})(i);}
</script>
</body>
</html>
点击相应数字会弹出对应的值,点1弹1,点2弹2.
js的工厂模式
工厂模式
考虑到在 ECMAScript 中无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节,如下面的例子所示:
function createPerson(name,age,job){var o = new Object();o.name = name;o.age = age;o.job = job;o.sayName = function(){ alert(this.name);}return o;}var person1 = createPerson('Grey',27,'Doctor');
函数 createPerson()能够根据接受的参数来构建一个包含所有必要信息的 Person 对象。可以无数次地调用这个函数,而每次它都会返回一个包含三个属性一个方法的对象。工厂模式虽然解决了创建\多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。
主要好处就是可以消除对象间的耦合,通过使用工程方法而不是new关键字。将所有实例化的代码集中在一个位置防止代码重复。
工厂模式解决了重复实例化的问题 ,但还有一个问题,那就是识别问题,因为根本无法 搞清楚他们到底是哪个对象的实例。
js 的prototype原型理解讲解
在我理解看来,prototype不外乎就两个基础的作用:
1.动态的添加类的属性和方法
2.复制原类的内容
我们先来看第一个:
首先来定义一个简单的Person类;
var Person = function(name,age){
//指定该类的属性为参数值
this.name = name;
this.age = age;
//为该类指定一个talk方法
this.talk = function(){
alert("talk");
};
};
下面我们来生成Person 的实例
var zhangsan = new Person("zhangsan",19);
var lisi = new Person("lisi",19);
1
2
这样我们产生了两个Person 的实例,zhangsan 和lisi ,原先Person里有个方法talk,而我们生成实例的时候,该talk会被再次生成一遍,因此这是极其不好的,因为假如我们要产生100个Person 的实例,该talk()就会被创建100次,而这很有可能导致内存溢出。那有没有办法只创建一次talk()呢,答案是有的!就是用prototype!
先来看一段代码:
//照样是定义一个Person的类
var Person = function(name,age){
//指定该类的属性为参数值
this.name = name;
this.age = age;
//我们这里不再为Person设定talk方法
};
};
再次来生成Person 的实例
var zhangsan = new Person("zhangsan",19);
var lisi = new Person("lisi",19);
这里创建完毕后,我们得知,zhangsan和lisi都没有talk的方法,我们现在用prototype给他们加上
Person.prototype.talk = function(){
alert("talk");
};
此时,Person所有的实例都拥有了这个方法
zhangsan.talk();//"talk"
lisi,talk();//"talk"
既然第一种用处搞清楚了,现在来看第二种用处。
所谓第二种用处就是复制原类的内容。
//新建一个类Person2
var Person2 = function(name,age){};
Person2.prototype = new Person();
此时的Person里的内容已经全部拷贝到Person2里面了
This
this总是返回一个对象,即返回属性或方法当前所在的对象。
对象的属性可以赋给另一个对象,所以属性所在的当前对象是可变的,即this的指向是可变的。
样例:
var A = {name : '张三',describe : function(){return '姓名:' + this.name;}
};
var B = {name : '李四'
}B.describe = A.describe;B.describe();
结果:“姓名:李四”
再看一个例子:
var A = {name : '张三',describe : function(){return '姓名:' + this.name;}
};
var name = '李四'
f = A.describe;
f();
结果也是“姓名:李四”,因为这时this指向f运行时所在的对象——顶层window
this的使用场合
1、全局环境——无论this是不是在函数内部,只要是在全局环境下运行,this就是指顶层对象window
2、构造函数——指的是实例对象
eg:
var Obj = function(p){this.p = p;
}
Obj.prototype.a = function(){return this.p;
}
var obj = new Obj('color');
obj.a();
obj.p;
结果是都返回"color"
上面代码定义了一个构造函数Obj,由于this指向实例对象,所以在Obj中定义this.p,相当于定义实例对象有一个p属性,然后m方法可以返回这个p属性。
3、对象的方法
var obj = {foo : function(){console.log(this);}
};obj.foo();//obj
只有直接在obj对象上调用foo方法,this才会指向obj,其他用法时,this都指向代码块当前所在的对象。
New 的自定义实现创建
new是怎么创建实例对象的;首先创建一个构造函数;
function Person(name,age){
this.name=name;
this.age=age;
};
var p=new Person(‘ck’,16)
通过new可以创建构造函数Person的实例对象。那么我们怎么去实现这一功能的呢?下面就为大家揭晓谜底:
function New(fn){return function(){var obj={'__proto__':fn.prototype};fn.apply(obj,arguments);return obj;}}var p1=New(Person)('chen',22)p1.name;//打印chen p1.age;//打印22p1 instanceof Person // true 验证p1是否是Person的实例对象。
这样我们就可以自定义创建一个实例对象了。
1、首先呢通过创建一个New函数,该函数接收一个参数(要创建实例对象的构造函数);
2、然后函数内部返回一个匿名函数
3、匿名函数内部返回一个对象,该对象就是构造函数的实例对象;那么这里有一个问题就是我们要使New函数可以通用,那么就要知道每一个构造函数的实例对象的属性;所以我在匿名函数的内部通过apply()方法用构造函数替换当前对象obj;同时将构造函数的执行上下文指向obj;故obj对象就继承了构造函数的相关属性。
这里解释下apply
apply:方法能劫持另外一个对象的方法,继承另外一个对象的属性.
Function.apply(obj,args)方法能接收两个参数
obj:这个对象将代替Function类里this对象
args:这个是数组,它将作为参数传给Function(args–>arguments)
call:和apply的意思一样,只不过是参数列表不一样.
Function.call(obj,[param1[,param2[,…[,paramN]]]])
obj:这个对象将代替Function类里this对象
params:这个是一个参数列表
apply示例:
<script type="text/javascript"> /*定义一个人类*/ function Person(name,age) { this.name=name; this.age=age; } /*定义一个学生类*/ functionStudent(name,age,grade) { Person.apply(this,arguments); this.grade=grade; } //创建一个学生类 var student=new Student("zhangsan",21,"一年级"); //测试 alert("name:"+student.name+"\n"+"age:"+student.age+"\n"+"grade:"+student.grade); //大家可以看到测试结果name:zhangsan age:21 grade:一年级 //学生类里面我没有给name和age属性赋值啊,为什么又存在这两个属性的值呢,这个就是apply的神奇之处.
</script>
分析: Person.apply(this,arguments);
this:在创建对象在这个时候代表的是student
arguments:是一个数组,也就是[“zhangsan”,”21”,”一年级”];
也就是通俗一点讲就是:用student去执行Person这个类里面的内容,在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student对象里面
附: typeof xxx:判断变量的数据类型; xxx instanceof Array:精确判断变量是否属于某一类型。
这篇关于6.22 js学习笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!