定义 || 赋值

    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。
        @定义函数的作用:除了指明函数作用域,同时定义函数体结构——包括函数体内部的变量定义和函数定,此过程递归。

            alert(a);    //function a(){}
alert(b); //function b(){}
alert(c); //undefined
var a = "a";
function a() {}
function b() {}
var b = "b";
var c = "c";
var c = function() {}
alert(a); //a
alert(b); //b
alert(c); //function(){} ①虽然第一个 alert(a) 在最前面,但是你会发现它输出的值竟然是 function a() {},这说明,函数定义确实在整个程序执行之前就已经完成了。
②再来看 b,函数 b 定义在变量 b 之前,但是第一个 alert(b) 输出的仍然是 function b() {},这说明,变量定义确实不对变量做什么,仅仅是声明它的作用域而已,它不会覆盖函数定义。
③最后看 c,第一个 alert(c) 输出的是 undefined,这说明 var c = function() {} 不是对函数 c 定义,仅仅是定义一个变量 c 和一个匿名函数。
④再来看第二个 alert(a),你会发现输出的竟然是 a,这说明赋值语句确实是在执行过程中完成的,因此,它覆盖了函数 a 的定义。
⑤第二个 alert(b) 当然也一样,输出的是 b,这说明不管赋值语句写在函数定义之前还是函数定义之后,对一个跟函数同名的变量赋值总会覆盖函数定义。
⑥第二个 alert(c) 输出的是 function() {},这说明,赋值语句是顺序执行的,后面的赋值覆盖了前面的赋值,不管赋的值是函数还是其它对象。

    3-变量赋值
      对于弱类型的JavaScript,声明变量不需要声明其类型。
      随之的问题,在使用 直接量和引用量 却混乱一片:
        ①var x = "111";  var y = x;  x = "222";  alert(y);
          在JavaScript中,此时y值为111,即字符串的赋值是直接量操作,直接把数据赋值给y的存储空间。
          在java等语言中,y的值为222,即x在存储器中将地址(指针)赋给变量y。
        ②var x = ["111"];  var y = x;  x[0] = "222";  alert(y[0]);
          在JavaScript中,此时却与①不同,y[0]值为222,引用量操作,即x把在存储器中的地址(指针)赋给了y。
        ③var x = ["111"];  var y = x;  x = ["222","333"];  alert(y[0]);
          在Javascript中,此时y的值又是111,即此赋值又是直接量操作。
      JavaScript解析器 对不同类型的差异:
        var x = "xxxx";  var y = ["11","22"];
        ①在字符串中,解析器直接把字符串赋给变量x(直接量)。
        ②在数组中,解析器把数组的指针赋给变量y(引用量)。
        上述问题②中,x[o] = "222"由于没有给x新定义值,没有新开辟存储空间,只修改了它存储空间里的数据,故还是引用量。
        上述问题③中,创建var x = ["111"]时,解析器在内存中为数组创建存储空间,x则获得该空间的地址(指针),
               再执行x = ["2","3"]给数组新定义值时,解析器会开辟新存储空间放这个数组,x则为新存储空间的指针。

      由上述可知,JavaScript的变量能存储直接量 也能存储引用量。
        在大字符串连接 和 循环里赋值等地方,需留意此变量特性对执行效率的影响。

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 变量、函数与原型链的更多相关文章

  1. JavaScript之继承(原型链)

    JavaScript之继承(原型链) 我们知道继承是oo语言中不可缺少的一部分,对于JavaScript也是如此.一般的继承有两种方式:其一,接口继承,只继承方法的签名:其二,实现继承,继承实际的方法 ...

  2. JavaScript高级内容:原型链、继承、执行上下文、作用域链、闭包

    了解这些问题,我先一步步来看,先从基础说起,然后引出这些概念. 本文只用实例验证结果,并做简要说明,给大家增加些印象,因为单独一项拿出来都需要大篇幅讲解. 1.值类型 & 引用类型 funct ...

  3. JavaScript 随笔2 面向对象 原型链 继承

    第六章 面向对象的程序设计 1.创建对象的几种方式 A)工厂模式 function CreatObj(name,sex,age){ this.name=name; this.sex=sex; this ...

  4. javascript 重难点(原型链 this) 理解总有一个过程,不要急,循序渐进!

    开始补充: 1. 将函数定义作为对象的属性,称之为对象方法.2. this的指向是由它所在函数调用的上下文决定的(语境),而不是由它所在函数定义的上下文决定的.3. 因为当一个函数作为函数而不是方法来 ...

  5. javascript中继承(一)-----原型链继承的个人理解

    [寒暄]好久没有更新博客了,说来话长,因为我下定决心要从一个后台程序员转为Front End,其间走过了一段漫长而艰辛的时光,今天跟大家分享下自己对javascript中原型链继承的理解. 总的说来, ...

  6. Javascript之继承(原型链方式)

    1.原型链 原型链是JavaScript中继承的主要方法. 每个构造函数都拥有一个原型对象,原型对象都包含一个指向构造函数的指针(constructor),实例都包含一个指向原型对象的内部指针(__p ...

  7. javascript 面向对象 new 关键字 原型链 构造函数

    JavaScript面向对象JavaScript 语言使用构造函数(constructor)作为对象的模板.所谓"构造函数",就是专门用来生成实例对象的函数.它就是对象的模板,描述 ...

  8. javascript 创建对象及对象原型链属性介绍

    我们知道javascript里定义一个普通对象的方法,如: let obj = {}; obj.num = 1; obj.string = 'string'; obj.func = function( ...

  9. javascript基础学习系列-原型链模式

    1.demo代码如下: 2.画图如下: 3.规则: 1)每一个函数数据类型(普通函数/类)都有一个天生自带的属性:prototype(原型),并且这个属性是一个对象数据类型的值 2)并且prototy ...

随机推荐

  1. dpkg:警告:无法找到软件包 XXXX 问题解决

    原地址:http://blog.csdn.net/wise622453/article/details/7905253 纠结了好久在ubuntu server 上 出现的 一大批“ dpkg:警告:无 ...

  2. linux 如何清理僵尸进程

    今天在维护服务器的时候,发现有5个nova-novncproxy的僵尸进程. 26327 ?        S      0:05  \_ /usr/bin/python /usr/bin/nova- ...

  3. linux 搭建hexo博客

    搭建环境: CentOS 6.5 1.安装git的编译包 yum -y install gcc zlib-devel openssl-devel perl cpio expat-devel gette ...

  4. Solr5.3.1通过copyField设置多个field(字段)同时检索

    如果业务需要我们对多个field同时进行检索,有没有什么好的办法呢?非常幸运的是Solr为我们提供了copyField对多个field进行索引和检索.然而配置也非常简单. 修改schame.xml,添 ...

  5. js判空

    2014年9月3日 11:36:10 转载的: http://blog.sina.com.cn/s/blog_755168af0100vsik.html typeof用法 typeof的运算数未定义, ...

  6. Java面向对象的多态

    Java中多态的概念是面向对象中除封装和继承外非常重要的知识点,也是Java面向对象三大特性最后一个特性 多态其实就是指对象存在的多种形态,多态分为引用多态和方法多态 引用多态的含义就是:父类的引用可 ...

  7. 【动态规划】The Triangle

    问题 E: [动态规划]The Triangle 时间限制: 1 Sec  内存限制: 128 MB提交: 24  解决: 24[提交][状态][讨论版] 题目描述 73 88 1 02 7 4 44 ...

  8. iOS 手势操作:拖动、捏合、旋转、点按、长按、轻扫、自定义

    1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. iOS 系统在 3.2 以后,他提供了一些常用的手势(UIGestureReco ...

  9. git merge和个git rebase的区别

    http://stackoverflow.com/questions/16666089/whats-the-difference-between-git-merge-and-git-rebase/16 ...

  10. 运行基准测试hadoop集群中的问题:org.apache.hadoop.ipc.RemoteException: java.io.IOException: File /benchmarks/TestDFSIO/io_data/test_

    在master(即:host2)中执行 hadoop jar hadoop-test-1.1.2.jar DFSCIOTest -write -nrFiles 12 -fileSize 10240 - ...