~_~
继续开坑
html负责数据的显示,css负责样式的显示,javascript负责完成页面的交互
javascript有很多框架(类似于OC中的Fundation Cocoa框架集等),最早的是prototype.js现在很少用
现在最流行的几种比如 jQuery 有很多插件,Extjs等,DWR框架(可以达到直接通过js调用java的代码)
一、
①可直接在html中在script标签中写
<script type=”text/javascript> (类似于css的<style type=”text/css”>..
/*js代码*/
</script>
②也可以引入外部文件(常用) css中用link 通过src指定外部文件位置
<script type=”text/javascript” src=”hello.js></script>
注意:<script>标签**不能自结束!**
alert(“”);
二、基本语法相关
很多东西 常用技巧习惯语法和java很像
①javascript是动态类型语言,而C java等是静态类型语言,动态类型语言是运行到哪读哪
②变量:js只能通过var来创建变量,eg: var a = 20 注意for(var i;i<=10;i++) 不要习惯性把var写成int等 住手这不是c/java啊喂 xxxx
注意:当在函数内部没有使用var来声明变量的时候,这个变量就会作为全局变量声明!所以在函数中定义变量一定要使用var
③函数: 通过function来创建函数
方法一: function fn1() { }
方法二:var x=function(){ return a;}
然后x(); 就是这个函数
方法三:function fn2(){} var y=fn2;
(仅函数名 不带括号)
(理解..其实都一个原理,指针 内存等) 函数名字可以通过改指针改,这是静态语言无法做到的
④注释:同java
(html)通过<input type=”xxx”></input>
标签 等来插入按钮等 然后可以添加事件 比如xxx可以为button,则为添加一个按钮
⑤数据类型相关 常用
alert(typeof a);
查看a的类型 注对于数组等对象而言返回object 对于函数返回function
强制类型转换:Number(a)
(java中为(Number)a) 如果强制转换一个非数字的值为Number会得到一个NaN的值
parseInt(a)
可将字符串开头的几个数字转换为Int ,但如果开头不是数字则NaN
a instanceof Array 判断as是不是Array的实例 是则返回true
布尔类型 true false 在js中,除了NaN,undefined,0这三个类型以外,其余皆为true ( 然后就可以通过这个特性搞事情
比如if(a) 等等
三、面向对象、原型(详细原理见二部分引用外部文章)
js中没有“类”的概念(ruby python也是) js的对象是基于原型拷贝的
动态语言一般都基于原型拷贝 只有一个根对象
“类”的定义
function Person(name,age){
this.name=name; (定义了Person的一个属性为name)
this.age= age;
this.mmm=”ssssss”; (定义了Persion的一个属性为mmm)
}
必须要用this声明,如果没有this声明则仅仅只是函数的一个局部变量而不是类的属性
就算要在类里面创建函数 也需要this! eg :this.abc= function(){}
js中每创建一个对象都存在一个function行为,占有内存,因为这个function行为属于一个属性,而java中不会这样,function不属于类的属性。
var p1= new Person(“jack”,10);
alert(p1.name);
除了点语法以外,也可以通过对象[“属性字符串”]完成对属性的调用
如alert(p1[“name”];
在js中对于对象而言 ,可以通过for in来遍历对象的属性 可以获取对象中所有的显示声明的属性
e.g.for (var a in p1){}
要显示p1的所有属性 遍历输出之 即可for(var i in p1) {alert(p1[i]}
常用对象:查库。
二部分引用外部文章:理解(重要,此文写得非常详细清晰)
Javascript中的函数、this以及原型
链接:http://www.cnblogs.com/xfrog/archive/2013/06/16/3138293.html
关于函数
在Javascript中函数实际上就是一个对象,具有引用类型的特征,所以你可以将函数直接传递给变量,这个变量将表示指向函数“对象”的指针,例如:
function test(message){
alert(message);
}
var f = test;
f('hello world');
你也可以直接将函数申明赋值给变量:
var f = function(message){
alert(message);
};
f('hello world');
在这种情况下,函数申明中可以省略函数名称,因为此时名称已经没有任何意义,我们可直接通过变量f来调用函数。
通过Function类型,我们可以更好地理解函数即对象:
var f = new Function("message","alert(message);");
f('hello world');
关于this
this可以看成调用函数的实际作用域上下文。比较以下函数的执行结果:
function test(){
this.property = 'hello world';
}
test();
alert(window.property); //由于在全局范围内调用,test函数中的this实际指向全局对象(window)
var obj = {};
test.call(obj); //通过call第一个参数指定执行上下文范围,所以test函数中this指向obj实例。
alert(obj.property);
var obj2 = {};
obj2.test2 = test; //将obj2实例方法test指向 全局test方法
obj2.test2(); //由于是在obj2上调用test方法,所以test函数中的this也指向了obj2实例
alert(obj2.property);
定义类型
在Javascript中可以定义构造函数,构造函数与一般函数没有任何区别,在创建实例时,如果我们使用了new关键字,那么这个函数就具有构造函数的特性,否则就是一般函数,如下所示,我们定义了一个Person类型:
function Person(){
this.name = 'xfrog';
this.Say = function(){
alert(this.name);
};
}
当使用new关键字时,可以创建一个新的Person对象实例:
var p1 = new Person();
p1.Say();
如果不使用new关键字,将直接执行Person函数,由于执行上下文为全局范围,故name属性和Say方法将被添加到window对象:
Person(); Say(); window.Say();
原型
注意上述Person的定义方式,当使用new来创建Person实例时,将会执行Person构造函数,也就是会声明name属性和Say方法,这样可能产生效率问题,注意以下代码:
var p1 = new Person(); var p2 = new Person(); var test = p1.Say == p2.Say;
比较p1和p2两个Say函数指针,返回false,表示每个Person实例中的Say方法都是独立的,而事实上Say函数的功能是完全一样的,我们完全没有必要为每个对象重新分配Say函数”对象“,如果Person实例很多,将会造成大量的内存耗用。
如果将Say函数提取出来放入全局执行范围,似乎可解决次问题:
>
>
function Person(){ this.name = 'xfrog'; this.Say = say; } function say(){ alert(this.name); } var p1 = new Person(); var p2 = new Person(); alert(p1.Say == p2.Say); p1.name = 'wang'; p1.Say();
由于this始终和执行上下文相关,p1和p2实例中的Say方法中会正确地返回对应实例的name属性。但是,使用此方式有违面向对象的思想,也失去了类型密封的原则。还会造成大量的全局函数。
为了解决这些缺点,Javascript引出了原型的概念,简单理解,原型可以看成是类型的共享区,原型本身是一个对象,而对象中的属性对于类型来说是共享的。Javascript中每个类型通过prototype属性来表示原型,通过这个属性可指定共享方法:
>
>
function Person(){ } Person.prototype.name = 'xfrog'; Person.prototype.Say = function(){ alert(this.name); }; var p1 = new Person(); var p2 = new Person(); alert(p1.Say == p2.Say); //返回true
为什么这里可以通过p1.Say来访问Say方法呢?这是因为ECMAScript标准规定了类型属性的查找顺序:先在类型的实例上查找,如果没有则继续在类型原型上查找,这一查找路径采用短路算法,即找到首个后即返回,考虑如下代码:
>
>
function Person(){ this.name = 'wang'; } Person.prototype.name = 'xfrog'; Person.prototype.Say = function(){ alert(this.name); } var p1 = new Person(); p1.Say(); //将返回wang
上面提到prototype实际上是一个对象,那么我们是否可以直接访问呢? 在一些浏览器实现(如Chrome、Fixfox等)的确可通过实例的proto属性来访问内部的prototype对象,这种特征表明Javascript引擎在每个对象的内部都是通过一个变量来保存对prototype的引用,这保证了prototype对应整个类型的实例来说是共享的,例如,你可在Chrome浏览器内使用如下方式来访问Say方法:
p1.__proto__["Say"]();
由于原型是一个对象,我们可以直接将一个对象赋值给prototype:
>
>
function Person(){ } Person.prototype = {name:'xfrog', Say:function(){ alert(this.name); }};
注意这个方式下,实际上是完全替换了Person的prototype,这与上面Person.prototype.name方式还是有细微差异的,这是因为任何类型,Javascript引擎都会添加默认的prototype,在这个prototype中包含一个对构造函数的引用,即原型对象属性constructor,所以通常使用替代prototype方式时,我们需要手动加上constructor属性:
>
>
Person.prototype = { constructor: Person, name :'xfrog', Say:function(){ alert(this.name); } }
注意,由于prototype对于整个类型是共享的,那么在prototype中的引用类型可能会存在问题,前面的Say函数作为一个对象,也是引用类型,所以每个实例中的Say都指向原型对象中的同一个函数,这本身没有问题,也是我们使用原型的初衷,但对于其他引用对象,可能结果并不是我们想要的:
>
>
function Person(){ } Person.prototype = { name: 'xfrog', obj : { age: 18 }, Say : function(){ alert(this.obj.age); } }; var p1 = new Person(); var p2 = new Person(); p1.obj.age = 20; p1.Say(); p2.Say();
p2.Say返回的是20,这是因为obj属性作为原型属性是共享的,在内存中只存在一个实例,所以通过p1修改后,p2只能得到修改后的状态。如果要避免此情况,可将obj属性放到实例中:
function Person(){ this.obj = { age: 18 }; }