Java和JavaScript的关系就是雷锋和雷峰塔的关系,也就是没有任何关系。JavaScript是一个运行在浏览器里面的语言,Node.js是运行在服务器端的JavaScript。
由于前端的HTML和CSS都没有判断和循环,因此需要一门真正的程序语言来表达逻辑,这就是js的作用。如果浏览器没有JavaScript来表达逻辑,所有的页面交互逻辑就只能通过与后端通信实现,用户就需要不停地刷新页面,浏览体验非常差,那么web应用就无法取代本地app。
变量
JavaScript 中局部变量只可能通过两种方式声明,一个是作为函数参数,另一个是通过 var 关键字声明。
// 全局变量
var foo = 1;
var bar = 2;
var i = 2;
function test(i) {
i = 5; // 局部变量
var foo = 3; // 局部变量
bar = 4; // 全局变量,因为没有var关键字
}
数据类型
JavaScript has 7 built-in types:6 primitive and 1 object type。可以利用typeof
查看类型。
-
String
没有字符类型。 -
Boolean
- undefined、null、0、NaN、 "" 在逻辑表达式中都是false。与之相对,非空字符串、非0数字都是true。
- Boolean-->number:true转为1,false转为0.
- 逻辑表达式不一定返回boolean值。Boolean()函数才会。
-
“” || “hello”
返回“hello”
-
“hello” || true
返回“hello”
-
true || “hello”
返回true
-
-
Number
- 没有细分类型。计算两个整数的除法不会自动丢掉小数部分,而是像一个普通的计算器一样,直接计算出小数。
-
NaN
:由于变量没有类型,所以编译器并不会防止字符串除以数字作为表达式的可能,这样计算的结果是NaN
,表示不是一个数字。 -
Infinity
,-Infinity
:2/0, -2/0的结果。
-
object
In JavaScript, an object is a collection of name/value pairs. 即便如此,对象依然会有方法。原因是在js中,函数的代码本身可以作为value。 -
Array
In JavaScript, arrays are just objects and the indices are just property names. -
null
表示一个指针没有指向任何对象。可用于初始化或者清空一个指针变量。 -
undefined
- 只有变量声明,没有赋值,那么这个变量的类型是undefined,并不是程序报错。因为在动态语言中,什么类型的值都可以放在变量里面。
- 没有变量声明,就使用一个变量,就会报错 not defined。
- In JavaScript, when a property doesn't exist and you simply mention that property in an object, JavaScript engine creates that property for you. 所以
var a = {};console.log(a.b);
并不会报错,而是返回undefined。
运算符
-
==
用来比较数值相等,会自动转换类型。‘4’== 4会返回true,false == 0也返回true。但是js不会把字符用ASCII转化为数字。 -
===
先检查类型,不一致就直接返回false。 -
+
既是字符串连接也是数值运算符。优先做字符串的连接。‘123’+ 10
得到‘12310’
。 -
*
只是数值运算符。‘123’*1 + 10
得到133
,‘Simons’*3
得到NaN
,不会像Python一样去复制字符串。 - isNaN()
-
NaN == NaN
和NaN === NaN
都返回false。也就是说判断是不是NaN不能用这两个符号。 - 会自动转换类型。isNaN('123')返回false,isNaN(false)返回false。
-
Objects
1. 对象的创建
1.1 创建一般对象
var person = new Object();
// 键不需要提前声明,直接用就好。
person.age = 18;
嵌套的对象必须先创建,才能为其属性赋值:
var person = new Object();
person.age = 18;
person.name = new Object(); //没有这句,下一句就要报错。
person.name.firstName = "sun";
更简单易读的创建对象的方法:
var person = {
age: 18,
name: {
firstName: "sun",
lastName: "bo" //最后一个键值对儿不加逗号
}
}
1.2 创建函数对象
创建的myCircle对象有三个属性:{ radius: 10, getArea: (), getPerimeter: () }
function Circle (radius) {
this.radius = radius;
this.getArea = function () {
return Math.PI * Math.pow(this.radius, 2);
}
this.getPerimeter = function () {
return 2 * Math.PI * this.radius;
}
}
// 没有new就变成function call了,但是这个函数并没有返回值,是它的属性才有。
// 因此myCircle就不能得到赋值。
var myCircle = new Circle(10);
myCircle
要是函数的代码不像一个Class的样子呢?答案是,得到一个没有属性的对象:{ }
function Circle (radius) {
return Math.PI * Math.pow(radius, 2);
}
var myCircle = new Circle(10);
公共代码放在prototype中:
function Circle (radius) {
this.radius = radius;
}
Circle.prototype.getArea = function () {
return Math.PI * Math.pow(this.radius, 2);
}
var myCircle = new Circle(10);
var myOtherCircle = new Circle(20);
2. 属性的访问
利用点或者方括号。用方括号的时候,键必须加引号,否则会当做变量。
3. 属性的遍历
类似于for-each loop,因为对象并没有长度一说。数组有。
var myPet = {
name: "小Q",
color: "brown",
age: 4
}
for (var prop in myPet) {
console.log(prop + ": " + myPet[prop]);
}
4. this关键字
在函数嵌套中,内层函数里的 "this" keyword points to the global object,而不是当前对象.(算得上是js的一个bug)
var circle = {
radius: 10,
getArea: function () {
console.log(this);
var increaseRadius = function () {
this.radius = 20; // 指向了全局变量
};
increaseRadius();
console.log(this.radius); // 又指向了当前对象
return Math.PI * Math.pow(this.radius, 2);
}
};
console.log(circle.getArea());
输出:
Object { radius: 10, getArea: getArea(), color: "red" }
10
314.1592653589793
查看全局变量:
window.radius
20
解决办法:在this指向当前对象的时候,把他的值保存下来!
var circle = {
radius: 10,
getArea: function () {
var self = this; // 把当前对象的地址保存再变量中
console.log(this);
var increaseRadius = function () {
self.radius = 20;
};
increaseRadius();
console.log(this.radius);
return Math.PI * Math.pow(this.radius, 2);
}
};
console.log(circle.getArea());
Functions
创建
function 方法名称(参数列表){
...
}
var 方法名 = function(参数列表){
...
}
奇葩特点:
函数调用只匹配名字,不看参数个数。
相同函数名,相同参数列表,的两个函数不会报错,而是会覆盖。
相同函数名,不同参数列表,的两个函数不会重载,而是会覆盖。
在方法声明中有一个隐藏的内置对象(数组),arguments,封装所有的实际传过来的参数。
1. First-class Function
JavaScript中的函数是First-class Function:you can carry the code of a function around.
- 允许把函数的代码本身赋给变量。
function multiply(y) {
return 3*y;
}
var a = multiply; // 传递函数的代码,而不是函数的返回值。
a(4);
>>12
- 允许把函数的代码作为返回值赋给变量。
function makeMultiplier (multiplier) {
var myFunc = function (x) {
return multiplier * x;
};
return myFunc; // 把函数的代码作为返回值
}
var multiplyBy3 = makeMutiplier(3);
multiplyBy3(10);
>>30
- 允许把函数代码作为参数进行传递
function doOperationOn (x, operation) {
return operation(x);
}
var result = doOperationOn(5, multiplyBy3);
result;
>>15
This profoundly changes how you code in JavaScript and makes JavaScript the wrong language to learn as your first programming language.
2. 函数也是对象
In JavaScript,函数也是对象。但是有两个层面的含义。
- 只有带this的变量才会是函数对象里面的属性,毕竟this指向当前对象。
function multiply(y) {
return 3*y;
}
multiply(4);
>>12
new multiply(4);
>>{ }
function multiply(y) {
var x =3;
return x*y;
}
multiply(4);
>>12
new multiply(4);
>>{ }
function multiply(y) {
this.x =3;
return x*y;
}
multiply(4);
>>12
new multiply(4);
>>{ x: 3 }
- 给函数名设置属性。
function multiply(y) {
return 3*y;
}
multiply.version = "v1.0";
这样设置的version属性,藏的就很深:
图片1.png
3. Passing variables by value or by reference
The truth is that underneath the hood in the JavaScript engine everything is actually passed and copied by value.
The difference /why one is really called passed by reference and one passed by value/ really comes because of the way the objects and primitives are stored in memory.
Arrays
数组就是对象:
- 用console.log()输出数组,是对象的键值对形式。以为数字键。
var array = new Array();
// 在js中,变量没有类型,数组里放的元素可以不同质。
array[0] = "sun";
array[1] = 18;
array[2] = function (name) {
console.log("Hello, " + name);
};
array[3] = { pet: "小Q" };
图片1.png
- 既然本质上是对象,也就可以不用数字作为键。
var array = ["aa", "bb", "cc"]; //java里面用的是大括号
array.dd = "ee";
array
>> Array [ "aa", "bb", "cc" ]
// 非数字键对应的value不显示!但是可以遍历出来。
for (var prop in array) {
console.log(array[prop]);
}
>> aa
bb
cc
ee
数组长度不固定,可以随便越界。
var array = ["aa", "bb", "cc"];
array.[100] = "dd"; // 中间的位置都是undefined
for (var i = 0; i<array.length; i++ ) {
console.log(array[i]);
}
方法:
join(分隔符):将数组中的元素按照指定的分隔符拼接为字符串。
push():向数组的末尾添加一个或更多元素,并返回新的长度。
日期对象
var date = new Date();
数学对象
Math.方法名();
random():返回 0 ~ 1 之间的随机数。 含0不含1
round(x):四舍五入
取整:
- ceil(x):变大,到达天花板。
- floor(x):变小
正则表达式对象
创建
- var reg = new RegExp("正则表达式");
- var reg = /正则表达式/;
方法
test(参数):验证指定的字符串是否符合正则定义的规范
正则表达式简介:
单个字符:[可选字符]
量词符号:?表示有没有。*、+表示数量的增加。{m,n}:表示闭区间。
开始结束符号:^开始,$结束。
全局对象global
使用这个对象的方法,可以不加global直接用。具体方法可以查w3c。
isNaN()
URL的编解码。因为网址在传输的时候必须要转化成字节流。
网友评论