1.js作用域
<script>
//函数外声明定义的变量就是全局变量
//网页中所有脚本和函数均可使用
var quanju="全局变量";
function test1(){
//name变量在test1函数中
//name变量是局部变量
//局部变量的作用域只能在当前函数中
//每一个函数中都可以声明定义名称相同的变量,而不被影响
var name="zhangsan";
//window.alert("name=="+name);
window.alert("quanju=="+quanju);
}
function test2(){
var name="lisi";
//window.alert("name=="+name);
window.alert("quanju=="+quanju);
}
//如果变量在函数内没有声明(没有使用 var 关键字),该变量为全局变量。
function test3(){
testname="没有声明的变量"; //是window对象的变量【全局变量】
//window.alert("testname=="+testname);
}
function test4(){
window.alert("testname=="+testname);
}
//test1();
//test2();
//test3();
//test4();
//函数参数只在函数内起作用,是局部变量。
function test5(myname){
window.alert("myname=="+myname);
}
function test6(){
window.alert("myname=="+myname);
}
//test5("张三");
//test6("张三");
//你的全局变量,或者函数,可以覆盖 window 对象的变量或者函数。
window.doxname="dox"; // window 对象的变量
var doxname="hello"; //全局变量
function test7(){
//全局变量会覆盖window 对象的变量
window.alert("doxname=="+doxname);
}
//test7();
//局部变量,包括 window 对象可以覆盖全局变量和函数。
function test8(){
var doxname="你好"; //局部变量
//局部变量可以覆盖window 对象变量和函数也可以覆盖全局变量和函数
window.alert("doxname=="+doxname);
}
test8();
</script>
2.闭包
「函数」和「函数内部能访问到的变量」的总和,就是一个闭包
错误的认识:1.闭包不是函数套函数
错误的认识:2.闭包中的函数是可以没有return语句
<script>
function test1(){
var local="变量"; //局部变量
function foo(){
return local;
}
return foo;
}
function test2(){
//调用test1函数,得到foo函数,被t1接收
var t1=test1();
//调用t1就是就是访问foo函数
var val=t1();
alert(val);
}
test2();
</script>
3.原型和原型链
<script>
/*
var arr1 = [1, 0, 0, 8, 6];
var arr2 = [1, 0, 0, 8, 6, 1, 1];
arr1.sort(function(n1, n2) {
return n1 - n2;
});
arr2.sort(function(n1, n2) {
return n1 - n2;
});
console.log(arr1); //[0, 0, 1, 6, 8]
console.log(arr2); //[0, 0, 1, 1, 1, 6, 8]
console.log(arr1 === arr2);//false
console.log(arr1.sort === arr2.sort);//true
*/
//上述代码中console.log(arr1 === arr2);为false,因为
//arr1和arr2中的元素和元素个数不同。
//console.log(arr1.sort === arr2.sort);为true,因为
//arr1和arr2使用的是相同的sort方法,sort方法是arr1和arr2的公共方法
//JavaScript是如何做到让sort方法是arr1和arr2的公共方法?
/*
var arr1 = [1, 0, 0, 8, 6];
var arr2 = [1, 0, 0, 8, 6, 1, 1];
//数组求和方法
arr1.getSum = function() {
var sum = 0;
for(var i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
}
//console.log(arr1.getSum()); //输出15
//console.log(arr2.getSum());//控制台报错: Uncaught TypeError: arr2.getSum is not a function
*/
//console.log(arr2.getSum());输出错误,因为
//因为你的变量arr2没有getSum()方法。
//那么有没有解决方案,函数只定义一次,然后提供给不同的变量使用呢?
//答案是有的。
var arr1 = [1, 0, 0, 8, 6];
var arr2 = [1, 0, 0, 8, 6, 1, 1];
//将getSum定义为原型方法
Array.prototype.getSum = function() {
var sum = 0;
for(var i = 0; i < this.length; i++) {
sum += this[i];
}
return sum;
}
console.log(arr1.getSum()); //控制台输出15
console.log(arr2.getSum()); //控制台输出17
//Array.prototype.getSum = function() {......}将getSum()方法给了Array.prototype
//此时getSum()方法就成了原型方法,由此可知Array.prototype是数组的原型对象。
//得到的结果是对象arr1和arr2就可以共享getSum方法了。
//OOP---面向对象程序设计
//在OOP的计算机编程架构中,首先需要创建一个类,然后有这个类来创建对象。
/* java 实例
public class Student{
int age=23; //类中定义属性
public void test1(){ 类中定义方法
}
}
Student stu1=new Student(); //通过上面的Student类创建对象stu1
//如果创建对象的类中有属性和方法,那么在通过这个类创建对象的时候,
//类中有属性和方法会被复制给创建的这个对象。
*/
//我们现在认为student()----类
function student(){
this.name="zhangsan";
this.test1=function(){
}
}
//创建实例
var stu1=new student();
//在 JavaScript 中不会把类中的属性和方法复制给实例
//而是在对象实例stu1和它的构造器【student()】之间建立一个链接【__proto__属性】,
//__proto__属性是从构造函数的prototype属性派生的。
//之后通过上溯原型链,在构造器中找到这些属性和方法。
//alert(stu1.__proto__); //[object Object]
//alert(student.prototype); //[object Object]
//函数上面都有一个属性(prototype),prototype属性指向了函数的原型对象(函数名称.prototype)。
//即使你只定义了一个空函数,也存在一个prototype的属性。
//例子尽管我们什么都不做,但是浏览器已经在内存中创建了两个对象:
//student()[函数]和student.prototype,其中,我们称student为构造函数,因为我们后面要用到这个函数来
// new对象,student.prototype称为Person的原型对象,简称原型。
//alert(stu1.constructor);
student.prototype.age=23;
var stu2=new student();
alert(stu2.age);
alert(stu1.age);
</script>