1.if else结构
if
结构先判断一个表达式的布尔值,然后根据布尔值的真伪,执行不同的语句。所谓布尔值,指的是 JavaScript 的两个特殊值,true
表示“真”,false
表示“伪”
if (布尔值){
语句;
}
if (m !== 1) {
if (n === 2) {
console.log('hello');
}
} else {
console.log('world');
}
// world
2.switch 结构
switch (x) {
case 1:
console.log('x 等于1');
break;
case 2:
console.log('x 等于2');
break;
default:
console.log('x 等于其他值');
}
3.三元运算符
(条件) ? 表达式1 : 表达式2
上面代码中,如果“条件”为true
,则返回“表达式1”的值,否则返回“表达式2”的值。
//例子一
var myVar;
console.log(
myVar ?
'myVar has a value' :
'myVar does not have a value'
)
// myVar does not have a value
//例子二
var msg = '数字' + n + '是' + (n % 2 === 0 ? '偶数' : '奇数');
4.循环语句
1.while循环
var i = 0;
while (i < 100) {
console.log('i 当前为:' + i);
i = i + 1;
}
while (true) {
console.log('Hello, world');
}
2.for循环
for (初始化表达式; 条件; 递增表达式)
语句
// 或者
for (初始化表达式; 条件; 递增表达式) {
语句
}
var x = 3;
for (var i = 0; i < x; i++) {
console.log(i);
}
// 0
// 1
// 2
for ( ; ; ){
console.log('Hello World');
}
//死循环
5.数据类型
1.字符串与数组
var s = 'hello';
s[0] // "h"
s[1] // "e"
s[4] // "o"
// 直接对字符串使用方括号运算符
'hello'[1] // "e"
//如果方括号中的数字超过字符串的长度,或者方括号中根本不是数字,则返回undefined
'abc'[3] // undefined
'abc'[-1] // undefined
'abc'['x'] // undefined
//但是,字符串与数组的相似性仅此而已。实际上,无法改变字符串之中的单个字符。
var s = 'hello';
delete s[0];
s // "hello"
s[1] = 'a';
s // "hello"
s[5] = '!';
s // "hello" //字符串内部的单个字符无法改变和增删,这些操作会默默地失败
2.length 属性
length
属性返回字符串的长度,该属性也是无法改变的。
var s = 'hello';
s.length // 5
s.length = 3;
s.length // 5
s.length = 7;
s.length // 5
3.Base64 转码
Base64 就是一种编码方法,可以将任意值转成 0~9、A~Z、a-z、+
和/
这64个字符组成的可打印字符。使用它的主要目的,不是为了加密,而是为了不出现特殊字符,简化程序的处理。
btoa()
:任意值转为 Base64 编码atob()
:Base64 编码转为原来的值
var string = 'Hello World!';
btoa(string) // "SGVsbG8gV29ybGQh"
atob('SGVsbG8gV29ybGQh') // "Hello World!"
这两个方法不适合非 ASCII 码的字符,会报错
要将非 ASCII 码字符转为 Base64 编码,必须中间插入一个转码环节,再使用这两个方法
function b64Encode(str) {
return btoa(encodeURIComponent(str));
}
function b64Decode(str) {
return decodeURIComponent(atob(str));
}
b64Encode('你好') // "JUU0JUJEJUEwJUU1JUE1JUJE"
b64Decode('JUU0JUJEJUEwJUU1JUE1JUJE') // "你好"
4.对象
var obj = {
foo: 'Hello',
bar: 'World'
};
对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用。
var obj = {
p: function (x) {
return 2 * x;
}
};
obj.p(1) // 2
var p = function(){
console.log(123)
}
p() //123
//对象的读值与赋值
var obj = {};
obj.foo = 'Hello';
obj['bar'] = 'World';
//属性的查看
var obj = {
key1: 1,
key2: 2
};
Object.keys(obj);
// ['key1', 'key2']
用defineProperty函数定义属性
var obj = Object.defineProperty({}, 'p', {
value: 123,
configurable: false
});
obj.p // 123
delete obj.p // false
6.属性是否存在 in运算符
in
运算符用于检查对象是否包含某个属性(注意,检查的是键名,不是键值),如果包含就返回true
,否则返回false
。它的左边是一个字符串,表示属性名,右边是一个对象
var obj = { p: 1 };
'p' in obj // true
'toString' in obj // true
//in运算符的一个问题是,它不能识别哪些属性是对象自身的,哪些属性是继承的。就像上面代码中,对象obj本身并没有toString属性,但是in运算符会返回true,因为这个属性是继承的。
//对象都继承了toString属性
用hasOwnProperty
方法判断一下,是否为对象自身的属性。
var obj = {};
if ('toString' in obj) {
console.log(obj.hasOwnProperty('toString')) // false
}
7.循环
for...in
循环有两个使用注意点。
- 它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。
- 它不仅遍历对象自身的属性,还遍历继承的属性。
var obj = {a: 1, b: 2, c: 3};
for (var i in obj) {
console.log('键名:', i);
console.log('键值:', obj[i]);
}
// 键名: a
// 键值: 1
// 键名: b
// 键值: 2
// 键名: c
// 键值: 3
如果继承的属性是可遍历的,那么就会被for...in循环遍历到。但是,一般情况下,都是只想遍历对象自身的属性,所以使用for...in的时候,应该结合使用hasOwnProperty方法,在循环内部判断一下,某个属性是否为对象自身的属性。
var person = { name: '老张' };
for (var key in person) {
if (person.hasOwnProperty(key)) {
console.log(key);
}
}
// name
8.构造函数,原型对象,实例对象
1.构造函数
构造函数:用来在创建对象时初始化对象。特点:构造函数名一般为大写字母开头;与new运算符一起 使用来实例化对象。
这里注意一点,所有的函数实际上都可以作为构造函数,因为js里面没有类的概念,你可以认为构造函 数就是类,而使用构造函数创建对象这个过程等同于类的实例化过程
function Person(){} //Person构造函数
var p=new Person(); //Person构造函数创建对象,也可叫做实例化
2.原型对象
原型:构造函数在创建的过程中,系统自动创建出来与构造函数相关联的一个空的对象。 可以由构造函数.prototype来访问到。
举例:在实例化对象p的过程中,系统就自动创建出了构造函数的原型,即Person.prototype. 注意:每个对象的proto属性指向自身构造函数的prototype;
constructor属性是原型对象的属性,指向这个原型对象所对应的构造函数。
function Person(){}
var p = new Person() //
console.log(Person.prototype) //{}
Person.prototype.myname = 'hello world'
console.log(Person.prototype.constructor) //[Function: Person]
console.log(Person.prototype) //{ myname: 'hello world' }
console.log(p.__proto__) //{ myname: 'hello world' }
console.log(typeof p) //object
9.函数
js三种声明函数的方式
//方法一
function print(s) {
console.log(s);
}
//方法二
var print = function(s) {
console.log(s);
};
//方法三
var obj = {
p: function (x) {
return 2 * x;
}
};
10.函数名的提升
JavaScript 引擎将函数名视同变量名,所以采用function
命令声明函数时,整个函数会像变量声明一样,被提升到代码头部。所以,下面的代码不会报错。
f();
function f() {}
表面上,上面代码好像在声明之前就调用了函数f
。但是实际上,由于“变量提升”,函数f
被提升到了代码头部,也就是在调用之前已经声明了。但是,如果采用赋值语句定义函数,JavaScript 就会报错。
f();
var f = function (){};
// TypeError: undefined is not a function
上面的代码等同于下面的形式。
var f;
f();
f = function () {};
上面代码第二行,调用f
的时候,f
只是被声明了,还没有被赋值,等于undefined
,所以会报错。
注意,如果像下面例子那样,采用function
命令和var
赋值语句声明同一个函数,由于存在函数提升,最后会采用var
赋值语句的定义。
var f = function () {
console.log('1');
}
function f() {
console.log('2');
}
f() // 1
上面例子中,表面上后面声明的函数f
,应该覆盖前面的var
赋值语句,但是由于存在函数提升,实际上正好反过来。