您现在的位置:首页 >> 前端 >> 内容

js之原型链

时间:2018/7/5 11:31:16 点击:

  核心提示:一.变量类型和计算1.值类型 vs 引用类型值类型 ,特点:每个变量都能存储各自的值,不会相互影响。var a = 100; var b = a; a = 200; console.log(b)...

一.变量类型和计算

1.值类型 vs 引用类型
值类型 ,特点:每个变量都能存储各自的值,不会相互影响。
                var a = 100;
		var b = a;
		a = 200;
		console.log(b); //100

上面不光number类型是这个结果,像string,boolean,undefined类型也是一样的结果。

引用类型,包括对象,数组,函数。

                var a = {age: 21};
		var b = a;
		b.age = 100;
		console.log(a.age); //100

比较上面两个例子:值类型在运算的过程中,如果将一个变量赋值给另一个变量,会把值复制一份给它。

而引用类型并不会复制一份给它,因为引用类型一般都比较大,如果复制一份过去的话很消耗内存,所以引用类型赋值给另一个变量的时候,实质是指向一个对象类型的指针。

2.typeof运算符

		console.log(typeof(undefined));  //undefined
		console.log(typeof('abc'));   //string
		console.log(typeof(123));    //number
		console.log(typeof(true));   //boolean
		console.log(typeof({}));  //object
		console.log(typeof([]));  //object
		console.log(typeof(null));  //object
		console.log(typeof(console.log));  //function
从上面例子可以看出。1. typeof运算符只能区分值类型的数据类型 。2.typeof运算符的结果有六种,分别是:

string number undefined boolean object function

3.变量计算----强制类型转换。

字符串拼接

    var a = 100 + 10;  //110
    var b = 100 + "10";  //10010  这个是string类型

==运算符
    100 == '100';  //true
    0 == '';  //true
    null == undefined;  //true

从上面结果可以看出来,我们要谨慎使用==运算符。

if语句

    var a = true;
    if (a) {
    	//...
    }
    var b = 100;
    if (b) {
    	//...
    }
    var c = '';
    if (c) {
    	//...
    }

逻辑运算符

		console.log(10 && 0);  //0
		console.log('' || 'abc');  //'abc'
		console.log(!window.abc);  //true
		
		//判断一个变量会被当作true还是false
		var a = 100;
		console.log(!!a);  //true
1.问题:何时使用 === ,何时使用 ==?
    if (obj.a == null) {
    	//推荐使用jQuery的写法,即我们需要判断的如obj.a === null || obj.a === undefined的时候我们使用==符号
      (obj.a == null,相当于obj.a === null || obj.a === undefined)。别的情况都使用===符号。
    }

2.问题:js中有哪些内置函数

Object Array String Number Boolean Function Date RegExp Error

3.问题:js按存储方式分为哪几种类型,各自有哪些特点?

1.值类型,特点:每一个变量的值分块存储在内存当中。

2.引用类型,特点:变量共用一个内存块,为了节省内存空间。

4.如何理解JSON?

JSON和Math一样,是一个JS对象,JSON同时还是一种格式。

json提供两种API:

		var a = JSON.stringify({a:10, b:20});  //转换为字符串
		console.log(typeof(a));  //string  
		var b = JSON.parse('{"a":10, "b":20}');  //转换成对象
		console.log(typeof(b));  //object

二.原型和原型链-----构造函数

构造函数

构造函数和普通函数的区别:

一般规则:构造函数都应该以大写字母开头,eg: function Person() {...}

非构造函数都应该以小写字母开头,eg: function person() {...}

调用方式:任何函数,只要它能够通过new操作符来调用,那么它就可以作为构造函数;如果没用通过new操作符调用,那它和普通函数就没有区别。

		function Person(name,age,job) {
		  this.name = name;
		  this.age = age;
		  this.job = job;
		  this.sayName = function() {
		    alert(this.name);
		  }
		}

		//当作构造函数使用
		var person = new Person("zhangsan", 22, "doctor");   //this ==> person
		person.sayName();  //"zhangsan"

		//当作普通函数使用
		Person("lisi", 30, "teacher");  //this ==> window
		window.sayName();  //"lisi"
构造函数----扩展

1.var a = {} 其实是 var a = new Object() 的语法糖,即他的构造函数是Object

2.var a = [] 其实是 var a = new Array() 的语法糖,即他的构造函数是Array

3.function Foo() {...} 其实是 var Foo = new Function(....),即他的构造函数是Function

4.使用instanceof判断一个函数是否是一个变量的构造函数

注:实际开发中推荐使用前面这种简便的写法。

原型规则

5条原型规则,原型规则是学习原型链的基础。

1.所有的引用类型(数组,对象,函数),都具有对象特性,即可自由扩展属性(除了null以外)。

2.所有的引用类型(数组,对象,函数),都有一个__proto__(隐式原型)属性,属性值是一个普通的对象。

3.所有的函数,都有一个prototype(显示原型)属性,属性值也是一个普通的对象。

4.所有的引用类型(数组,对象,函数),__proto__属性值指向他的构造函数的prototype属性值。

		var obj = {}; obj.a = 100;
		var arr = []; arr.a = 100;
		function fn () {}
		fn.a = 100;

		console.log(obj.__proto__);
		console.log(arr.__proto__);
		console.log(fn.__proto__);

		console.log(fn.prototype);

		console.log(obj.__proto__ === Object.prototype);

5.当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去他的__proto__(即它的构造函数的prototype)中寻找。

		//构造函数
		function Foo(name,age) {
		  this.name = name;
		}
		Foo.prototype.alertName = function () {
		  alert(this.name);
		}

		//创建实例
		var f = new Foo('zhangsan');
		f.printName = function() {
		  console.log(this.name);
		}

		//测试
		f.printName();
		f.alertName();  //f中找不到alertName这个属性,根据第五条原型规则会去f的__proto__属性中寻找,
                即去f的构造函数Foo中的prototype属性中寻找。
注意:js中this永远指向的是最后调用它的对象

小知识:循环对象自身的属性:

    var item;
    for (item in f) {
      //高级浏览器已经在for in 中屏蔽了来自原型的属性
      //但是这里建议大家还是加上这个判断。保证程序的健壮性
      if (f.hasOwnproperty(item)) {
        console.log(item);
      }
    }

原型链

		function Foo(name,age) {
		  this.name = name;
		}
		Foo.prototype.alertName = function () {
		  alert(this.name);
		}

		//创建实例
		var f = new Foo('zhangsan');
		f.printName = function() {
		  console.log(this.name);
		}

		//测试
		f.printName();
		f.alertName();
		f.toString();  //去f.__proto__.__proto__中找
js之原型链

 

原型链----instanceof

用于判断引用类型属于哪个构造函数的方法。

f instanceof Foo 的判断逻辑是:

1.f 的__proto__一层一层往上,能否对应到Foo.prototype。

2.再试着判断f instanceof Object。

问题1:如何准确判断一个变量是数组类型?

		var one = [];
		console.log(one instanceof Array);  //true
		console.log(typeof(one));  //object,typeof是判断不了的
问题2:写一个原型链继承的例子。

写一个封装DOM查询的例子:

		function Elem (id) {
		  this.elem = document.getElementById(id);
		}

		Elem.prototype.html = function (val) {
		  var elem = this.elem;
		  if (val) {
		    elem.innerHTML = val;
		    return this;  //链式操作,关键在于return this,使用了他就相当于返回了p1,不写它自己也会返回
		  } else {
		    return elem.innerHTML;
		  }
		}

		Elem.prototype.on = function (type, fn) {
		  var elem = this.elem;
		  elem.addEventListener(type, fn);
		  return this;
		}

		var p1 = new Elem("p1");
		/*console.log(p1.html());*/
		/*p1.html("

hello world

"); p1.on("click", function () { console.log('click'); })*/ //上面注释的代码,我们使用链式语法来执行,理解一下链式语法 p1.html("

hello world

").on("click", function(){console.log("click")});

问题3:描述new一个对象的过程。

1.创建一个新对象。2.this指向这个新对象。 3.执行代码,即对this赋值。 4.返回this。

 

Tags:JS S之 之原 原型 
作者:网络 来源:sinat_4069