学习JS第七节——继承

1.继承的方式
  • 原型链
    继承了太多没用的属性
  • 借用构造函数(call方法)
function Person(name, age, sex) {
	this.name = name;
}

(1)不能继承构造函数的原型
(2)在视觉上省了空间,但是每次构造函数都要多走一个构造函数

  • 共享原型
Father.prototype.lastName  = "Deng";
function Father() {}
function Son() {}

Son.prototype = Father.prototype;
var son = new Son();
var father = new Father();

抽象为一个继承功能

Father.prototype.lastName  = "Deng";
function Father() {}
function Son() {}

//抽象为继承函数
function inherit(Target, Origin) {
	Target.prototype = Origin.prototype;
}
inherit(Son, Father);
var son = new Son();
//注意:后两个语句不能换位置
//一定要先继承再用
  • 圣杯模式(在共享原型上加上原型链的使用)
function inherit(Target, Origin) {
	//添加一个中间层构造函数
	function F {};
	//令中间层F的原型和Origin的原型相等,
	F.prototype = Origin.prototype;
	Target.prototype = new F();
	//new一个F(),是又创建了一个新的原型空间
	//这样即继承了Origin的属性,又可以添加自己的属性
	//此时对象构造器的指向为
	// son.__proto__ --> new F() --> Father.prototype --> 构造器constructor是Father
	//因此Target的构造器更改为自身
	Target.prototype.constructor = Target;
	//给Target增加一个属性超集uber,方便以后查看其继承自谁
	Target.prototype.uber = Origin.prototype;
}

使用闭包升级方法

function inherit(function() {
	var F = function() {};
	return function (Target, Origin) {
		F.prototype = Origin.prototype;
		Target.prototype = new F();
		Target.prototype.constructor = Target;
		Target.prototype.uber = Origin.prototype;
	}
}());
2.命名空间

管理变量,防止污染全局,适用于模块化开发

  • 命名空间
    利用对象{}中的内容可以是对象{},层层嵌套对象,形成分隔的命名空间
var org = {
	department1 : {
		person1 : {
			name : 'abc',
			age : 123
		},
		person2 : {
			name : 'b'
		}
	},
	department2 : {
		person1 : {},
		person2 : {}
	}
}

//使用某个变量
//方法一
org.department1.person1.name;
//方法二
var person1 = org.department1.person1;
person1.name;
  • webpack
  • 用闭包私有化变量
var init = (function() {
	var name = 'abc';
	function callName() {
		console.log(name);
	}

	return function() {
		callName();
	}
}())

//init返回的是函数,才能以函数的形式执行
//如果没有将callName放入函数中,就算callName本身是函数也不能这样执行
//这样会报错,说init不是一个函数
init();

在开发中,将所有的入口函数都命名为为init

3.链式调用(模仿jQuery)
//jQuery中的链式调用形式
$('div').css('background-color','red').width(100).height(100).css('position','absolute');
//可以在调用完一个对象属性方法后继续调用其他的
var person = {
	drink : function() {
		console.log('drink!');
		return this;
		//返回this重新指向对象
	},
	eat : function() {
		console.log('eat');
		return this;
	},
	sleep : function() {
		console.log('sleep');
		return this;
	}
}

//这样就可以链式调用函数方法
person.drink().sleep().eat();
4.访问属性的方法
  • 方法一:obj.name
    不够灵活,不能实现属性名的拼接

obj.name在系统内部中发生了自动转换,被转换为`obj[‘name’]

  • 方法二:obj['name'](建议使用这种,便于属性名字符拼接)
    注意:属性名必须加引号,不然不能识别
5.对象枚举
  • for in
var obj = {
	name : 'kathy',
	age : 13,
	sex : 'male'
}
//遍历
for(var prop in obj) {
	console.log(obj[prop]);
}

prop代表对象属性,可以被定义为任何变量,只是一个名字。

注意最后一行打印代码,不能写成obj.prop,因为系统内部的转换,见4,系统会将这行语句识别成obj的prop属性
且不能加引号成为obj[‘prop’],因为本身遍历时就已将属性保存到prop中,就是字符串,所以不用多此一举加引号

  • hasOwnProperty
obj.hasOwnProperty(prop);
//若属性时原型的将返回true

for in方法在遍历对象的属性时,会返回包括原型上的东西,因此有时造成冗余
for in返回的原型属性均是自己定义的属性,系统定义的属性并不返回

//在前面的代码中加入hasOwnProperty过滤原型的属性
for(var prop in obj) {
	if(obj.hasOwnProperty(prop)) {
		console.log(obj[prop]);
	}
}
  • in

判断属性是否属于对象

'height' in obj;
//注意属性要加引号,不加引号就是变量的意思,而变量不会在对象中

in与hasOwnProperty的区别是:
in只能判断对象是否能访问到这个属性,不能排除原型上的属性。

  • instanceof
    看A对象的原型链上有没有B的原型,是返回true
A instanceof B

判断是数组[]还是对象{}的三个方法:

(1)构造器constructor

[].cosntructor
//输出 function Array() {}

//注意对象要先定义,不能直接使用{}代表对象
var obj = {};
obj.constructor
//输出 function Object() {}

(2)instanceof Array

[] instanceof Array;
// true

var obj = {};
obj instanceof Array;
// false

(3)toString

Object.prototype.toString.call(要判断类型的)
//使用call改变this的指向,从而判断参数的类型
Object.prototype.toString.call([]);
// [object Array]

Object.prototype.toString.call(123);
// [object Number]

Object.prototype.toString.call({});
// [object Object]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值