渡一教育公开课web前端开发JavaScript精英课学习笔记(九)对象的继承、命名空间、对象属性枚举

继承

  1. 传统形式:原型链的模式。缺点:没用的属性和方法都继承下来。
  2. 借用构造函数:不能继承构造函数的原型。并且需要执行一次构造函数。
  3. 共享原型:一个构造函数的原型设置成想要继承的构造函数的原型。这样就实现了继承,但这不能随便改动自己的原型。
  4. 圣杯模式:完善共享原型模式,中间添加个对象。
 <script type = "text/javascript">
	//圣杯模式实现继承
	Father.prototype.lastName = "lin";
	function Father(){};
	function Son(){};
	function inherit(Target, Origin){
		//Target.prototype = Origin.prototype;
		function F(){};
		F.prototype = Origin.prototype;
		Target.prototype = new F();
		Target.prototype.constuctor = Target;
		Target.prototype.uber = Origin.prototype;
	}
	inherit(Son,Father);
	var son = new Son();
	console.log(son.__proto__);
</script>
 

命名空间

为了不让全局变量混淆,采用了定义一个全局对象,全局对象里包含多个对象,这些对象中存储每个功能的变量,这样就能区分开各功能模块的变量。这是个比较早期采用的方法。还可采用闭包的模式开发。

<script type = "text/javascript">
  var org ={
      department_one:{
          zhangsan:{
              name:"abc",
              age:123
          }
      },
      department_two:{
          lisi:{
              name:"efg",
              age:345
          }
      }
  }
  var zs = org.department_one.zhangsan;
  var ls = org.department_two.lisi;
  console.log(zs.name);
  console.log(ls.name);
  //使用 with 操作命名空间中的变量。
  with(org.department_one.zhangsan){
    console.log(name);
  }
  with(org.department_two.lisi){
    console.log(name);
  }
  </script>

实现链式调用

<script type = "text/javascript">
   var person = {
       smoke : function(){
           console.log("Smoking....cool!");
           return this;
       },
       drink : function(){
           console.log("Drinking...cool too !");
           return this;
       },
       perm : function(){
            console.log("Perming...cool cool cool !");
            return this;
       }
   }
   person.drink().perm().smoke().drink().smoke().perm().perm().smoke().smoke().drink().smoke();
</script>

对象属性的访问方式

person.card1 和  person['card1'] 都是访问 person 对象的 card1 属性。

引擎会把 person.card1 转成 person['card1'] 来访问属性。

<script type = "text/javascript">
   var person = {
    card1:{name:"中国银行"},
    card2:{name:"中国工商银行"},
    card3:{name:"中国建设银行"},
    card4:{name:"中国交通银行"},
    card5:{name:"汇丰银行"},
    card6:{name:"华夏银行"},
    card7:{name:"渤海银行"},
    card8:{name:"网商银行"},
    card9:function(){
        console.log("花呗");
    },
    __proto__:{number:"6200000000000"}
   }
   Object.prototype.abc = "123";
   console.log(person.card1);
   console.log(person.card7);
   for (const key in person) {
       //是否对象本身的属性,而不是继承来的。
       console.log(person.hasOwnProperty(key));
       if(typeof(person[key]) == "function"){
            person[key]();
       }
       else{
            console.log(person[key]);
       }
    }
    // in 操作符。对象 person 是否有card1 属性,包括原型链。
    console.log('card1' in person);
    function Demo(){}
    var demo = new Demo();
    // instanceof 操作符。对象 demo 的原型链上是否有 Demo 原型。
    console.log(demo instanceof Demo);
    console.log(demo instanceof Object);
    console.log([] instanceof Array);
    console.log([] instanceof Object);
    console.log(1 instanceof Object);
    console.log("abc" instanceof Object);
</script>

对象的深度复制

<script type = "text/javascript">
	var person = {
	 card1:{name:"中国银行"},
	 card2:{name:"中国工商银行"},
	 card1Name:function(){
		 return this.card1.name
	 },
	 cards:["中国银行","中国工商银行"],
	 card2Name:null
	}
	console.log(person.card2Name != null);
	function clone(obj1,obj2){
		obj2 = obj2 || {};
		for (const key in obj1) {
			if(obj1.hasOwnProperty(key)){
				if(typeof(person[key]) == "object" && person[key] != null){
					obj2[key] = (new Object().toString.call(person[key]) == "[object Array]") ? [] : {};
					clone(obj1[key],obj2[key]);
 				}else{
					obj2[key] = obj1[key];
				}
			}
		}
		return obj2;
	}
	var obj = {}
	var obj0 = clone(person,obj);
	console.log('obj.card1.name = ',obj.card1.name,'person.card1.name = ',person.card1.name);//修改前与person相同。
	obj.card1.name = "消除";//修改obj。
	console.log('obj.card1.name = ',obj.card1.name,'person.card1.name = ',person.card1.name);//修改obj后。
	console.log('obj.card1Name() = ',obj.card1Name(),'person.card1Name() = ' ,person.card1Name());//修改obj后。
	console.log('obj.cards = ',obj.cards,'person.cards = ' ,person.cards);
	console.log('person object = ',person);
	console.log('obj object = ',obj);
	console.log('obj0 object = ',obj0,obj0===obj);
 </script>
 

练习题:

console 输出结果是什么?

<script type = "text/javascript">
    var f = (
        function f(){
            return "1";
        },
        function g(){
            return 1;
        }
    )();
    console.log(typeof(f));
</script>
<script type = "text/javascript">
    var x = 1;
    if(function f(){}){
        //(function f(){}) 这个表达式判断完就销毁了。
        x += typeof f;//此时 f 没有定义 undefined
    }
    console.log(x);
</script>
<script type = "text/javascript">
    console.log(undefined == null);
    console.log(undefined === null);
    console.log(undefined == undefined);
    console.log(null == null);
    console.log(undefined === undefined);
    console.log(null === null);
    console.log(undefined == NaN);
    console.log(null == NaN);
    console.log(null === NaN);
    console.log(undefined === NaN);
    console.log(NaN === NaN);
    console.log(isNaN(100));
    console.log(parseInt("1a")==1);
    function myIsNaN(num){
        var ret = Number(num);
        ret += "";
        if(ret == "NaN"){
            return true;
        }else{
            return false;
        }
    }
    console.log(myIsNaN("123"));
    console.log({} == {});
    console.log([] == []);
</script>

this 指针

  1. 函数预编译过程 this --> window。
  2. 全局作用域里 this --> window。
  3. call/apply 可以改变函数运行时 this 指向。
  4. obj.func();func()里面的this指向obj。

this指针指向调用函数的对象,new 构造函数时使用闭包的特性产生新对象。

练习题

写出输出结果:

<script type = "text/javascript">
    //控制台输出结果是:?????????
    var name = "222";
    var a = {
        name : "111",
        say : function(){
            console.log(this.name);
        }
    }
    var fun = a.say;
    fun();
    a.say();
    var b = {
        name : "333",
        say : function(fun){
            fun();
        }
    }
    b.say(a.say);
    b.say = a.say;
    b.say();
</script>
<script type = "text/javascript">
	var a = 5;
	function Test(){
		// new 的时候系统添加 this 局部变量。
		// this = {
		// 	__proto__:test.prototype
		// }
		a = 0;
		console.log(a);//先找到局部变量 a ,输出。
		console.log(this.a);//找调用者里变量 a , 输出。
		var a;
		console.log(a);//先找到局部变量 a , 输出。
	}
	Test(); // 0,5,0
	new Test();// 0,undefined,0
</script>
<script type = "text/javascript">
	function print(){
		var marty = {
			name : "marty",
			printName : function(){console.log(this.name);}
		}
		var test1 = {name : "test1"};
		var test2 = {name : "test2"};
		var test3 = {name : "test3"};
		test3.printName = marty.printName;
		var printName2 = marty.printName.bind({name : 123});
        //bind方法作用是给函数 printName 设置 this 指向定义的{name:123}对象。
		marty.printName.call(test1);
		marty.printName.apply(test2);
		marty.printName();
		printName2();
		test3.pringName();
	}
	print();
</script>
<script type = "text/javascript">
	var bar = {a:"002"};
	function print(){
		bar.a = 'a';
		Object.prototype.b = 'b';
		return function inner(){
			console.log(bar.a);
			console.log(bar.b);
		}
	}
	print()();
</script>

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值