JavaScript 变量、函数与原型链
2014-11-07 22:59
218 查看
定义 || 赋值
1-函数的定义
函数定义的两种方式:
“定义式”函数:function fn(){ alert("哟,哟!"); }
“赋值式”函数:var fn = function(){ alert("切可闹!"); }
@页面加载时,浏览器会对JavaScript代码进行扫描,并将 定义式函数进行预处理(类似C等的编译)。【函数声明提升】
处理完再由上至下执行,遇到赋值式函数 则只是将函数赋值给一个变量,不进行预处理,待调用时才进行处理。
@在定义前面调用函数时,定义式函数正常执行,赋值式函数会报错 (提示:oFn is not a function)。
2-变量与函数的定义
变量:①var a; 定义变量a。
②var a = 123; 定义变量a,再给变量a赋值。
函数:①function fn(...){...} 声明函数fn。
②var oFn = function(...){...} 先定义变量oFn和一个匿名函数,再将匿名函数赋值给变量oFn。
@定义变量和定义函数都会先预处理,变量赋值则是在执行中完成。
@定义变量的作用:只是指明变量作用域。
有定义没赋值的变量 和 使用没定义的变量 值都为undefined。
@定义函数的作用:除了指明函数作用域,同时定义函数体结构——包括函数体内部的变量定义和函数定,此过程递归。
4-原型的定义和赋值
原型:如果构造器有个原型对象A,由构造器创建的对象实例(Object Instance)都复制于原型对象A。
①每个对象都有一个原型链,由自身向上包含一个或多个对象,本身为起始对象。
②在JavaScript中,一个对象 或 一个对象实例没有原型,不存在“持有某个原型”的说法,只存在“构造自某个原型”的说法。
构造器才有原型,<构造器>.prototype属性指向原型。
上述代码中:
①obj为对象实例,fn为一个构造器。
②obj.prototype; //undefined,对象实例没有原型。
fn.prototype; //[object Object],原型是一个对象。
③obj.constructor; //输出fn()的函数代码。
fn.construtor; //function Function(){[native code]},native code表示JavaScript引擎的内置函数。
obj.construtor == fn; //true,obj构造自fn。
④fn.prototype.construtor == fn; //true,函数原型的构造器 默认为函数本身。
对象实例 复制构造器的原型对象时,采用的是读遍历机制复制的。
读遍历机制:指仅当写某个实例的成员时,将成员信息复制到实例映像中。
即构造的新对象里面的属性 指向原型中的属性。读取对象实例的属性时,获取的是原型对象的属性值。
上述说明了读遍历机制 如何管理实例对象成员列表 和 原型中的对象成员。
①只有第一次对属性进行写操作时,才会在对象的成员列表中 添加该属性的记录。
②当obj1和obj2通过new构造出来,只是一个指向原型的引用,这样的读遍历 避免了创建对象实例可能的大量内存分配。
③obj2.value属性被赋值10时,obj2的成员表中添加了一个value成员并赋值10。
此成员表记录了对象发送了修改的成员名、值与类型。遵循2个原则:
a、保证在读取是首先访问。
b、对象中午指定属性时,遍历对象的整条原型链,直到原型为空或找到该属性。
④delete obj2.value删除的是成员表的属性。
原型的构造器
函数的原型 是内置的Object()构造器的一个实例。但该对象实例创建后,constructor属性总会先被赋值为当前函数。
究其根源在于构造器(构造函数)的原型(prototype)的constructor属性指向构造器本身。
上例中,myObject.protptype与new Object()没有实质区别,只是在创建时将myObject的constructor值赋值为自身。
函数与构造器并没有明显的界限:
当指定一个函数的prototype时,该函数就会成为构造器。
此时用new创建实例时,引擎会构造一个新对象,把这个新对象的原型链 连接向该函数prototype属性就可以了。
原型继承中的“原型复制”
通过设置 不同构造器创建出来的实例的constructor属性,能指向同个构造器。
obj1和obj2是由不同的两个构造器(MyObject和MyObjectEx)产生的实例。然而,两个alert都会输出true,即由两个不相同的构造器产生的实例,它们的constructor属性却指向了相同的构造器。这体现了原型继承中的“原型复制”。MyObjectEx的原型是由MyObject构造出来的对象实例,即obj1和obj2都是从MyObject原型中复制出来的对象,因此它们的constructor指向的都是MyObject!
1-函数的定义
函数定义的两种方式:
“定义式”函数:function fn(){ alert("哟,哟!"); }
“赋值式”函数:var fn = function(){ alert("切可闹!"); }
@页面加载时,浏览器会对JavaScript代码进行扫描,并将 定义式函数进行预处理(类似C等的编译)。【函数声明提升】
处理完再由上至下执行,遇到赋值式函数 则只是将函数赋值给一个变量,不进行预处理,待调用时才进行处理。
@在定义前面调用函数时,定义式函数正常执行,赋值式函数会报错 (提示:oFn is not a function)。
2-变量与函数的定义
变量:①var a; 定义变量a。
②var a = 123; 定义变量a,再给变量a赋值。
函数:①function fn(...){...} 声明函数fn。
②var oFn = function(...){...} 先定义变量oFn和一个匿名函数,再将匿名函数赋值给变量oFn。
@定义变量和定义函数都会先预处理,变量赋值则是在执行中完成。
@定义变量的作用:只是指明变量作用域。
有定义没赋值的变量 和 使用没定义的变量 值都为undefined。
@定义函数的作用:除了指明函数作用域,同时定义函数体结构——包括函数体内部的变量定义和函数定,此过程递归。
var x=""; var big = "这里是一大坨字符串..."; for (i=0; i<100; i++){ a += big; } x = a; //因为是字符串操作,使用直接量,每次循环都要操作大字符串,非常笨重,效率低下。如果改用引用量操作,即通过数组,效率甚至会提高十几倍: var s = "这里又是一大坨字符串..."; var a = []; for (i=0; i<100; i++){ a[i] = s; } s = a.join("");
4-原型的定义和赋值
原型:如果构造器有个原型对象A,由构造器创建的对象实例(Object Instance)都复制于原型对象A。
①每个对象都有一个原型链,由自身向上包含一个或多个对象,本身为起始对象。
②在JavaScript中,一个对象 或 一个对象实例没有原型,不存在“持有某个原型”的说法,只存在“构造自某个原型”的说法。
构造器才有原型,<构造器>.prototype属性指向原型。
function fn() { var name = "大虾"; var age = 23; function code() { alert("切克闹!"); }; } var obj = new fn();
上述代码中:
①obj为对象实例,fn为一个构造器。
②obj.prototype; //undefined,对象实例没有原型。
fn.prototype; //[object Object],原型是一个对象。
③obj.constructor; //输出fn()的函数代码。
fn.construtor; //function Function(){[native code]},native code表示JavaScript引擎的内置函数。
obj.construtor == fn; //true,obj构造自fn。
④fn.prototype.construtor == fn; //true,函数原型的构造器 默认为函数本身。
对象实例 复制构造器的原型对象时,采用的是读遍历机制复制的。
读遍历机制:指仅当写某个实例的成员时,将成员信息复制到实例映像中。
即构造的新对象里面的属性 指向原型中的属性。读取对象实例的属性时,获取的是原型对象的属性值。
Object.prototype.value = "abc"; var obj1 = new Object(); var obj2 = new Object(); obj2.value = 10; alert(obj1.value);//输出abc,读取的是原型Object中的value alert(obj2.value);//输出10,读取的是obj2成员列表中的value delete obj2.value;//删除obj2中的value,即在obj2的成员列表中将value删除掉 alert(obj2.value);//输出abc,读取的是原型Object中的value
上述说明了读遍历机制 如何管理实例对象成员列表 和 原型中的对象成员。
①只有第一次对属性进行写操作时,才会在对象的成员列表中 添加该属性的记录。
②当obj1和obj2通过new构造出来,只是一个指向原型的引用,这样的读遍历 避免了创建对象实例可能的大量内存分配。
③obj2.value属性被赋值10时,obj2的成员表中添加了一个value成员并赋值10。
此成员表记录了对象发送了修改的成员名、值与类型。遵循2个原则:
a、保证在读取是首先访问。
b、对象中午指定属性时,遍历对象的整条原型链,直到原型为空或找到该属性。
④delete obj2.value删除的是成员表的属性。
原型的构造器
函数的原型 是内置的Object()构造器的一个实例。但该对象实例创建后,constructor属性总会先被赋值为当前函数。
究其根源在于构造器(构造函数)的原型(prototype)的constructor属性指向构造器本身。
function MyObject() { } alert(MyObject.prototype.constructor == MyObject); //显示true,表明原型的构造器总是指向函数自身的 delete MyObject.prototype.constructor; //删除该成员(指向自身的原型构造器) alert(MyObject.prototype.constructor == Object); alert(MyObject.prototype.constructor == new Object().constructor); //删除操作使该成员指向了父代类原型中的值 //均显示为true
上例中,myObject.protptype与new Object()没有实质区别,只是在创建时将myObject的constructor值赋值为自身。
函数与构造器并没有明显的界限:
当指定一个函数的prototype时,该函数就会成为构造器。
此时用new创建实例时,引擎会构造一个新对象,把这个新对象的原型链 连接向该函数prototype属性就可以了。
原型继承中的“原型复制”
通过设置 不同构造器创建出来的实例的constructor属性,能指向同个构造器。
function MyObject() { } function MyObjectEx() { } MyObjectEx.prototype = new MyObject(); var obj1 = new MyObject(); var obj2 = new MyObjectEx(); alert(obj2.constructor == MyObject); //true alert(MyObjectEx.prototype.constructor == MyObject); //true
obj1和obj2是由不同的两个构造器(MyObject和MyObjectEx)产生的实例。然而,两个alert都会输出true,即由两个不相同的构造器产生的实例,它们的constructor属性却指向了相同的构造器。这体现了原型继承中的“原型复制”。MyObjectEx的原型是由MyObject构造出来的对象实例,即obj1和obj2都是从MyObject原型中复制出来的对象,因此它们的constructor指向的都是MyObject!
相关文章推荐
- JavaScript 变量、函数与原型链
- javascript 变量名 变成function 函数 名称
- javascript中变量没有块级作用域---函数内申明的变量在整个函数中都有效!
- javascript语言精粹。3、对象;4、函数;深入原型链,对象的原理!
- javascript中的回调函数中变量作用域
- JavaScript中通过闭包解决只能取得包含函数中任何变量最后一个值的问题
- Javascript的变量作用域居然可以跨越多个函数!
- javaScript 与 C# 函数、变量的访问
- javascript判断变量类型的自定义函数
- JavaScript与C#之间函数与变量的相互调用(转)
- javascript中运用闭包和自执行函数解决大量的全局变量问题
- javascript 调用其他页面的js函数或变量的脚本
- javascript调用父窗口的函数和变量
- 多个页面共享JAVASCRIPT 变量,对象,函数
- javascript判断变量类型的自定义函数
- javascript用arguments数组对象实现参数变量可变的函数
- JavaScript判断变量类型:typeof函数与constructor属性异同
- JavaScript基础:JS函数中声明的所有变量在整个函数中都是有定义的
- javascript 得到变量类型的函数
- freemarker 变量传递给javascript 函数