JavaScript基础(二)

一. 流程控制语句

1)条件控制

  1. if
if(条件表达式) ...//执行语句

if(条件表达式) {
    ...//执行代码块
}
  1. if…else…
if(条件表达式) {
   ...//执行代码块
} else {
   ...//执行代码块
}
  1. if…else if…else
if(条件表达式) {
   ...//执行代码块
} else if(条件表达式) {
   ...//执行代码块
} else {
   ...//执行代码块
}
  1. switch
switch(条件表达式) {
	case 表达式1:
		...//执行语句
		break;
	case 表达式2:
		...//执行语句
		break;
	...
	default:
		...//执行语句
		break;
}

2)循环

  1. for
    循环代码块一定的次数
  2. for/in
    循环遍历对象属性
for(key in Object) {}
  1. while
    当条件为true时循环代码块
  2. do…while
    使用情况和上边一样,当条件为true时循环指定代码块
do{
//TODO
} while(condition)
  1. continue 和 break
    break:跳出循环,继续执行循环之后的代码(如果有的话)
    continue:跳出当前迭代,继续执行该循环的下一迭代

二. JavaScript对象

1)什么是对象?

  在JavaScript中,一切皆对象,包括String、Boolean、Number、Function、Date、Array、Math、Error、RegExp、Object、Global、Window以及用户自定义对象。一个对象也是一个变量,它拥有自己的属性和方法,或者说它是一个可以包含多个其他变量的容器,这些变量以键值对的形式存在于对象内部。

2)对象的创建

  1. 手动写出对象的内容,所创建的对象又被称为 对象字面量,如下所示:
let person = {
	name: 'Mary',
	age: 20,
	greet: function() {
		alert('Hi! I am '+this.name)
 	}
  1. 通过类实例化一个对象
funtion Person(name, age) {
	this.name = name
	this.age = age
	this.greet = function() {
		alert('Hi! I am '+this.name)
	}
}
let person1 = new Person('Mary', 20)

js中本身没有class的概念,所以其实是通过构造函数的方式来实现。

  1. create() 额外的一个,就不单独拿出来写了
//接着上边的示例
let person2 = Object.create(person1)

create() 实际做的是从指定原型对象创建一个新的对象,比如例子中就是以person1为原型对象创建了person2。
补充:指定原型对象有时候很有用,我们可以不用再定义构造函数,也可以创建出一个不继承任何原型的绝对干净的对象。

3)访问与设置对象属性

  1. 点表示法
    接着上面创建的对象示例:
person.name //获取name属性值

person.greet //获取greet方法的定义
person.greet() //执行greet方法并获取结果

person.name = { //重新设置name属性值
	first: 'Mary',
	last: 'Smith'
}
person.name.first //子命名空间链式访问
person.phone = '13133802263' //设置一个新的属性

注意函数的不同访问方式以及对象中函数的调用!
  对象的属性仍然可以是一个对象,比如重新设置的name属性,这实际上创建了一个子命名空间,子命名空间中的属性直接链式使用点表示法就可以访问了。

  1. 括号表示法
person['name'] //获取name属性值, = person.name
person['name']['last'] //获取name中的last属性的值, =person.name.last

let foo = 'age'
person[foo] = 22 

  根据以上示例可以知道,括号表示法一个非常有用的地方就是,它不仅可以动态的去设置对象成员的值,还可以动态的去设置成员的名字,即括号中可以使用存储有属性名称的变量。

4)对象原型

  JavaScript是一种基于原型的语言,每个对象都有一个原型对象,从中继承属性和方法,这个原型对象也可以拥有它自己的原型对象,以此类推,这种关系又被称为原型链。话不多说,上例子~
  示例一:

//第一种
var foo = function() {}
console.log(foo.prototype)
//第二种
function foo() {}
console.log(foo.prototype)
//两次打印结果相同,都是默认的原型属性

每个新定义的函数都有一个默认的原型属性,与函数的定义方式无关。

  示例二:

//构造函数上的原型属性
function foo() {}
console.log(foo.prototype)
//实例上的原型属性
let instance = new foo()
console.log(instance.__proto__)
//or console.log(Object.getPrototypeOf(instance))

每个实例上都有一个原型属性,实例上的原型属性和构造函数上的原型属性指向的是同一个对象,注意两者的访问区别。

  示例三:

//接示例二
foo.prototype.attr1 = 'abcde'       
console.log(instance.__proto__.attr1)// result1: abcde
console.log(instance.attr1)        // result2: abcde

instance.__proto__.attr2 = 'aaa'
console.log(foo.prototype.attr2)   // result3: aaa
console.log(foo.attr2)             // result4: undefined
console.log(instance.attr2)        // result5: aaa

instance.attr3 = 'bbb'
console.log(instance.__proto__.attr3)// result6: undefined
console.log(foo.prototype.attr3)   // result7: undefined
console.log(foo.attr3)             // result8: undefined

  通过result2、result5可以发现,定义在原型对象上的属性也可以通过实例直接访问到,但是!!!并不是实例对象将原型对象中的属性复制了一份,而是通过原型链的方式访问到的,访问顺序如下:
1.先查找实例对象instance中有无目标属性;
2.没有的话,继续在实例的原型属性__proto__中查找有无目标属性;
3.没有的话,继续在__proto__属性的原型属性中查找……
最后,当所有的原型属性都被查找完了也没找到的话,该属性就是undefined;找到的话,返回找到的值。

三. js中的经典OOP特性:类

1)实现

class Person {
	name;  //可以直接省略这一步声明,也可以给一个值  name='';
	constructor(name) {
		this.name = name  //如果没有声明的话,会先创建一个name属性
	}
	greet() {
		console.log('This is' + this.name)
	}
}

  用class关键字声明类,constructor关键字声明构造函数。构造函数的执行过程如下:
1.先创建一个对象
2.将this绑定到所创建的对象,可以在构造函数以及之后的方法中通过this引用该对象
3.执行构造函数中的代码
4.返回这个对象

  当然,如果没有需要特殊初始化的东西,也可以省略构造函数,那么通过类进行实例化的时候就会调用默认的构造函数,生成一个只有原型属性的对象。

2)继承

class Employee extends Person{
	job;
	constructor(name, job){
		super(name)
		this.job = job
	}
	greet(){ //重写
		console.log('This is'+this.name+', my job is'+this.job)
	}
}

  用extends关键字继承类,在构造函数中初始化自己的新属性之前,需要先通过super()调用父类的构造函数;父类中的方法也会被继承过来,但是可以重写。

3)封装

class Employee extends Person{
	#age; //私有属性
	constructor(name, age){
		super(name)
		this.#age = age	
	}
	#showAge() { //私有方法
		console.log('I\'m '+this.#age+' years old.')	
	}
	greet() { 
		console.log('This is '+this.name)
		this.#showAge()
	}
}

let employee = new Employee('Jack', 20)
employee.greet() 
//This is Jack
//I'm 20 years old.
employee.showAge() 
//Uncaught TypeError: employee.showAge is not a function

  封装一个很重要的点就是不能由外部任意改变内部数据嘛(我理解的),所以这块涉及到一个私有数据属性,通过以上示例代码可以看到,私有属性由#标记,可以在内部访问,但是在外部访问的时候就会报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值