JavaScript(闭包、递归、枚举、构造函数、原型、原型链)

闭包

函数嵌套函数。内部函数就是闭包。
正常情况下,函数执行完后内部会被销毁(释放内部空间)。闭包,内部函数没有执行完成,外部函数、变量不会被销毁。
案例:
一、斐波那契数列

function fn(n) {
	let a = 0;
	let b = 1;
	let c = a + b;
	for(let i = 2; i < n; i++) {
		a = b;
		b = c;
		c = a + b;
	}
	return c;
}

递归

概念:函数自己调用自己,或者在自己函数调用的下级函数中调用自己。

案例:
一、斐波那契数列

function fn(n) {
	if (n == 1 || n == 2) return 1;
	return fn(n - 1) + fn(n - 2);
}

二、求和

function num(n) {
	if (n == 0) return 0;
	return num(n - 1) + n;
}

三、爬楼梯
假如楼梯有 n 个台阶,每次可以走 1 个或 2 个台阶,问走完这 n 个台阶有几种走法

function several(n) {
	if (n == 1) return 1;
	if (n == 2) return 2;
	return several(n - 1) + several(n - 2);
}

四、深拷贝
原理: clone(o) = new Object; 返回一个对象

function clone(o) {
	var obj = {};
	for (var key in o) {
		if (typeof o[key] == 'object') {
			obj[key] = clone(o[key]);
		} else {
			obj[key] = o[key];
		}
	}
	return obj;
}

枚举

JavaScript中本身是没有枚举这个概念的,但是在typeScript中有。
枚举的是指把所有相关的子数据都收集起来。

例如:

  enum Weekday {
    Monday,
    Tuseday,
    Wednesday,
    Thursday,
    Friday,
    Saturday,
    Sunday
  }

然后直接通过Weekday.Monday就可以获取到对应的值。

注意:第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。

我们在这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推。

构造函数

构造函数模式的目的就是为了创建一个自定义类,并且创建这个类的实例。
构造函数中拥有了类和实例的概念,并且实例和实例之间是相互独立的,即实例识别。

构造函数创建方式和普通函数没有区别。
不同:
1、构造函数习惯首字母大写。
2、调用方式不同。普通函数直接调用,构造函数需要使用new关键字来调用。

  function Person(name, age, gender) {
    this.name = name
    this.age = age
    this.gender = gender
    this.sayName = function () {
        alert(this.name);
    }
  }
  var per = new Person("张三", 18, "男");
  console.log(per); // 当我们直接在页面中打印一个对象时,事件上是输出的对象的toString()方法的返回值

上述代码中每创建一个Person构造函数,都会为对象添加一个sayName的方法。
构造函数每执行一次都会创建一个新的的方法。而且每个方法都一样,把这些方法单独放到一个地方就需要用到原型(prototype)。

原型

在JavaScript中,每当定义一个函数数据类型(普通函数、类)时候,都会天生自带一个prototype属性,这个属性指向函数的原型对象,并且这个属性是一个对象数据类型的值。
原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容,统一设置到原型对象中。

原型链

概念

在JavaScript中万物皆对象,对象和对象之间也有关系,并不是孤立存在的。
对象之间的继承关系,在JavaScript中是通过prototype对象指向父类对象,直到指向object对象为止,这样就形成了一个原型指向的链条。称之为原型链。
例如:person -> Person -> object

在原型链上查找属性比较耗时,对性能有副作用。访问不存在的属性时会遍历整个原型链,最后返回undefined。
遍历对象的属性时,原型链上的每个可枚举属性都会被枚举出来。
原型链的基本思想:就是利用原型让一个引用类型继承另一个引用类型的属性和方法,

检查对象是否具有自己定义的属性

要检查对象是否具有自己定义的属性,而不是其原型链上的某个属性,则必须使用所有对象从 Object.prototype 继承的 hasOwnProperty (en-US) 方法。
使用 in 检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true

  function Person() {}
  Person.prototype.a = 123;
  Person.prototype.sayHello = function () {
    alert("hello");
  };
  var person = new Person()
  console.log(person.a) // 123
  console.log(person.hasOwnProperty('a')); // false
  console.log('a'in person) // true

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到顶层Object位置。
Object是js中所有对象数据类型的基类(最顶层的类)在Object.prototype上没有__proto__这个属性。

Javascript继承机制的设计思想

```javascript
  function Person(name){
    this.name = name;
  }

  Person.prototype = { species : '男性' };

  var personA = new Person('张三');
  var personB = new Person('李四');

  alert(personA.species); // 男性
  alert(personB.species); // 男性
```

species属性放在prototype对象里,是两个实例对象共享的。只要修改了prototype对象,就会同时影响到两个实例对象。

prototype和__proto__的区别

prototype是函数才有的属性
__proto__是每个对象都有的属性
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值