javascript入门教程之学习笔记

呵呵,,好久没写文章了,,近来接触js比较多久顺便写个与js相关的文吧。

嗯,今天就谢谢与变量相关的东东吧,变量这东西只要你是敲代码的天天都得接触呢。

有人说变量有啥好写的?我不会告诉你Javascript里的变量很奇怪呢,没好好学一遍真的会被搞晕掉的。

好,先拿一篇已存的文,个人感觉写的还可以。

1.变量类型:基本类型和引用类型

    在js 中,基本类型:Number,Boolen,null,String,Underfined 存放在栈内存中,数据长度是固定的。
    而引用类型,Object存在堆内存中,数据长度是变化的(同时有栈内存中有一个指针指向这个Object的)。

2.引用类型的Object能任意指定新的成员,但是对于基本类型就是无效。
 

 代码如下 复制代码
   var str=’ahui’;
    str.name=’xiaoming’;//无效。
    alert(str.name);//undefined

3.关于复制
    基本类型:在新的栈内存中生成一个副本

     

 代码如下 复制代码
   var a='stra',b;
        
        b=a;//这里会所b数据拷贝到a所在的栈内存中
        
        b='strb';//a='stra'

引用类型:在新的栈内存中存一个相同的指针
    也就是说:其赋值不会开辟新内存空间。两个变量会保存完全相同的数据。

 代码如下 复制代码

        var objA=new Object();
        objA.name='stra';
        var objB=objA;//objB在栈内存的指针和objA在栈内存中的指针是值是相同的——指向同一个堆块
        objB.name='strb';
        alert(objA.name);//strb
        alert(objB.name);//strb

4.传参数——js中所有的参数都是按值传送的,而不是按引用。
    (这一点等同于复制)
    注:按值传递并不意味着你所传参数不会因为函数的执行而受影响。如果参数本身是引用类型,那么所复制的参数本身也包含相同的指针,参数的改变当然会影响到所传的变量。

 代码如下 复制代码

    var o=new Object;
    o.name='ahui';
    function func(obj){
    obj.name='This variable is changed';
    }
    func(o);
    alert(o.name);//This varibale is changed

变量的作用域

出处为javaeye的某贴——这世界就是这样,有些人喜欢制造问题,有人喜欢解决问题。制造问题的人为解决问题的人带来就业机会……

 代码如下 复制代码

<script type="text/javascript"> 
var a=100; 
var b=true; 
function test(){ 
    alert(a); 
    alert(b); 
    b=false; 
    alert(b); 
    var a=200; 
    alert(a/2); 
    alert(++Math.PI); 
    alert(Math.PI++); 

test();
</script>

什么第一个alert为undefined,而第二个为true。这问题也可以延伸为——alert(b)时怎么就会找外部的b,而alert(a)时就不会往外面找?!

我们都明白局部变量的优先级大于全局变量,或者说内围作用域的变量的优先级比外围的高。当JS引擎在当前作用域找不到此变量时,它就往外围的作用域找。不过,在这之前,有一个严肃的问题是,究竟当前作用域存不存在这个变量。像javascript这样的解释型语言,基本分为两个阶段,编译期(下面为符合大多数语言的称呼习惯,改叫预编译)与运行期。在预编译阶段,它是用函数来划分作用域,然后逐层为其以 var 声明的变量(下略称为var变量)与函数定义开辟内存空间,再然后对var变量进行特殊处理,统统赋初始值为undefined,如下图:

我们便可以推知,当前网页拥有两个a,一个b,一个test函数。如果在运行期用到除此以外的东东,如c函数或d变量啦,就会报未定义错误(用eval等非正常手段生成变量与函数的情况除外),此外,它们最多出现未赋值警告。

javascript的运行期是在为var变量与函数定义分配空间后立即执行,并且是逐行往下执行的。

    第1行它为外围作用域的a赋值为100
    第2行它为外围作用域的b赋值为true
    第3行进行test的作用域,我们简称为内围作用域。
    第4行就立即调用内围作用域的a,这时它还没有来得及赋值呢!不过它已经声明过了,因此默认为其赋值为undefined(在预编译阶段,见图),于是alert为undefined
    第5行就调用b时,JS引擎就拿起我画的图看了(笑),发现test的作用域内没有b,眼睛往外望,发现b了,而b在第二行就赋值为true,于是alert为true。
    第6行为一个赋值操作,把外围的b变量改赋为false。于是到第7行时,alert为false。以下说法不说了。

作为对比,我们改写一下例子:

 代码如下 复制代码
var a=100;
var b=true;
function test(){
    alert(a);
    alert(b);
    var b=false;
    alert(b);
    var a=200;
    alert(a/2);
    alert(++Math.PI);
    alert(Math.PI++);
}
test();

这时在test函数的作用域内,b也被声明了。

掌握预编译为var变量与函数定义分配空间这一事实后,许多问题就迎刃而解。我们看犀牛书上的一个例子。

 代码如下 复制代码
var scope = "global";
function f() {
    alert(scope);            
    var scope = "local";     
    alert(scope);            
}
f();

答案呼之欲出!

我们来看更复杂的例子。

 代码如下 复制代码
Object.prototype.test = 'wrong';
var test = 'right';
(function f() {
    alert(test);
})();

这个问题的难点在于,运行期时,又生成一同名变量,它是附着于Object.prototype,究竟哪一个距离F()的作用域近一些呢?!测试结果是var test。于是我们有了下图:

于是我们明白了,原来定义在函数外面的var变量并不位于window作用域的下一层。

我们继续加深难度。

 代码如下 复制代码
(function f() {
    alert(test);
})();
Object.prototype.test = 'ccc';
Object.test = "bbb"
window.test = "aaa";

报未定义错误,因为预编译期时没有符合要求的var变量,而在运行期时,和它同名的变量在调用时(第2行)也尚未建立起来!

如果这样呢?!

 代码如下 复制代码

Object.test = "bbb";
Object.prototype.test = 'ccc';
window.test = "aaa";
(function f() {
    alert(test);
})();

估计有很多人猜是bbb,其实是ccc!有人就不解了,不是对象的属性的优先级比其原型属性的优先级高吗???

无错,的确如此,不过对象的属性是这样定义的:

 代码如下 复制代码

var o = {test:"eee"}

Object.test = “XXX”

这样定义,为类属性,或称静态属性。类属性优先级都是比实例属性低的

通过这图也教育我们,一定要用局部变量啊,要不,一层层往上爬,效率是多么低啊。另外,这图也告诉我们,window是一个多么高级的存在啊(微软最爱听),Object都比它低一等,更别提什么继承问题啦!(在FF与IE中)

//颠覆常识的存在

 代码如下 复制代码

alert(window instanceof Object);
<script type="text/javascript"> //颠覆常识的存在 alert(window instanceof Object); </script>

 

搞定这个我们看最难的一题。类属性,实例属性,原型属性,极晚绑定的属性都考到了!不过实例属性与类属性已超出本文的讨论范围,恕不讨论了。这些也不太难,很容易google到的,自己google吧。

 代码如下 复制代码
function foo(){
  foo.abc = function(){alert('def')}
  this.abc = function(){alert('xyz')}
  abc = function(){alert('@@@@@')};
  var abc = function(){alert('$$$$$$')}
}
foo.prototype.abc = function(){alert('456');}
foo.abc = function(){alert('123');}
var f = new foo();
f.abc();
foo.abc();
abc();

蓝色理想的人说这题出得不好,有错。我说,有错才好,这样才能考出水平!十秒内做出正确答案,说明学会了。

答案:
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <p>

第一个为xyz,f.abc很明显就是调用其实例属性,通常构造函数是这样定义实例方法与实例属性的:</p> <blockquote>this.XXX = "XXXXXXXX"</blockquote> <p>第二个就是构造函数内部的foo.abc还是外部的foo.abc的问题了。我们只要搞清楚一点就可以,写在外面的那个是极晚绑定的成员,优先级极低,覆盖不了内部的同名成员。</p> <p>第三个为什么会报错呢?!因为在预编译阶段,foo()的作用域就有了一个abc变量, 因此abc = function(){alert('@@@@@')}就变不了window.abc = function(){alert('@@@@@')},而下面那一行就更甭提了。 而我们调用的是abc,全局变量的abc,浏览器会自动给它加上window.abc,就算不加上,沿途的Objcet也没有abc这个变量,因此它在f()的作用域外找不到abc,就报未定义错误!</p>

最后归纳一下,JS引擎有两个设置变量的机会。第一次在预编译时期,所有var变量会分配到各自的作用域中,值一律为undefined。第二次在运行期,由于是逐行执行,因此是可变的。我们可以通过eval与Function动态生成新的变量,它们的作用域都是可制定的,其他赋值语句,只是把变量固定于顶层作用域(window)中,或是仅仅是重新赋值。我们也可以用delete来删除对象的属性,迫使其往外走同名变量。with闭包会在其引用的对象的属性被删除后,在闭包的外围寻找与此属性同名的变量

我来做个总结吧,js里如果操作的是基本变量那么你可以按照你想的那样去做,如果是引用类型,那么你一定要好好想想,这是不是你想要的结果,切记!!!

 

时间: 2024-09-12 09:09:16

javascript入门教程之学习笔记的相关文章

php入门教程xml学习笔记

明确目标: 1.理解xml的结构:2.如何动态建立xml文件:3.如何读取和修改xml文件 一. xml的结构是树形结构: 这个好理解.简单写一个:  1 <pictures> 2   <picture> 3      <id>1</id> 4      <name>pic 1</name> 5   </picture> 6   <picture> 7      <id>2</id> 8

andengine入门教程之学习笔记

例子中主程序.launcher.ExampleLauncher主要继承自ExpandableListActivity的列表, 这里主要定义了另个枚举public enum ExampleGroup和enum Example ,平时因为像他们这样使用比较少,值得学习.  代码如下 复制代码 enum Example { // =========================================================== // Elements // ============

Grunt入门教程之学习笔记

我现在在几个小项目中一直在使用Node.js.在Node系统中有一些很强大的工具.我最喜欢的一个例子就是Grunt. Grunt是一种工具,允许您定义任务,然后通过命令运行他们,在命令行中运行:  代码如下 复制代码 grunt watch 这将启动一个watch任务,用来监控文件,我已经指定和运行指定的任务,只要这些文件变化了,就能监控到.在我的例子中,我已经在Grunt设置了只要当.js文件改变了就能检测JavaScript语法和压缩JavaScript和当.scss文件改变就能将Sass文

mysql数据库入门教程之学习笔记

mysql复习  一:复习前的准备  1:确认你已安装wamp  2:确认你已安装ecshop,并且ecshop的数据库名为shop     二   基础知识:  1.数据库的连接  mysql -u -p -h  -u 用户名  -p 密码  -h host主机  2:库级知识  2.1 显示数据库: show databases;  2.2 选择数据库: use dbname;  2.3 创建数据库: create database dbname charset utf8;  2.3 删除数

MySQL入门教程之学习笔记

慢速SQL:执行时间超过给定时间范围的查询就称为慢速查询. 在MySQL中如何记录慢速SQL? 答:可以在my.cnf中设置如下信息:   1 [mysqld]  2 ; enable the slow query log, default 10 seconds  3 log-slow-queries  4 ; log queries taking longer than 5 seconds  5 long_query_time = 5  6 ; log queries that don't u

javascript入门教程基础篇_javascript技巧

一. 简介 1. 什么是javascript JavaScript 是网景(Netscape)公司开发的一种基于客户端浏览器.面向(基于)对象.事件驱动式的网页脚本语言. 2. 为什么要使用javascript 表单验证 网页特效 小游戏 Ajax 3.快速入门 在程序中,如果想编写js代码,有两种办法: 1)在html文件中,在一对script标记中,直接编写 <script language='javascript'> document.write('hello'); </scrip

JavaScript入门教程之引用类型_javascript技巧

引用类型 引用类型是一种数据结构,用于将数据和功能组织在一起.它也常被称为类,但这种称呼并不妥当.尽管 ECMAScript从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和接口等基本结构.引用类型有时候也被称为对象定义,因为它们描述的是一类对象所具有的属性和方法. 前面提到过,引用类型的值便是对象,在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起,而对象则是某个特定引用类型的实例. var a=new Object(); 上面便声明了一个引用类

javascript入门教程:类的使用实例教程

下面我们来看个简单的js基础入门教程吧,类的使用创建修改等哦,javascript入门教程,创建,js教程,入门,javascript实例化 <script language="JavaScript" type="text/javascript"> <!-- var obj={}; //定义了一个空对象 var user={  name:"jack",  //定义了name属性,初始化为jack  favoriteColor:[

javascript入门教程:Dom创建删除表格

<html> <head> <title>javascript入门教程:Dom创建删除表格</title> </head> <body> <div id="tableTest"> </div> </body> </html> <script language="JavaScript" type="text/javascript&qu