JavaScript基础 —— 原型&&原型链
构造函数
function Foo(name, age) {
this.name = name;
this.age = age;
this.class = 'class-1';
//return this ; //默认有这一行
}
var f = new Foo('张三', 22);
var f1 = new Foo('李四', 29);
构造函数 - 扩展
var a={} 实际上是 var a=new Object() 的语法糖
var a=[] 实际上是 var a=new Array() 的语法糖
function Foo() {....} 实际上是 var Foo=new Function(...)
使用 instanceof 判断一个函数是不是一个变量的构造函数
原型规则和示例
- 全部的引用类型(数组、对象、函数),都具备对象属性(便可自有扩展的属性),
null
除外
- 全部的引用类型(数组、对象、函数),都有一个
__proto__
属性(隐式原型),属性值是一个普通的对象
var obj = { };
obj.x=100;
console.log(obj.__proto__);
// {constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
var arr = [];
arr.x = 200;
console.log(arr.__proto__);
// [constructor: ƒ, concat: ƒ, find: ƒ, findIndex: ƒ, pop: ƒ, …]
function fn() {};
fn.x = 300;
console.log(fn.__proto__);
// ƒ () { [native code] }
var d = null;
console.log(d.__proto__);
// Uncaught TypeError: Cannot read property '__proto__' of null
- 全部的
函数
,都有一个 prototype
属性(显式原型),属性值也是一个普通对象
console.log(fn.prototype);
// {constructor: ƒ}
- 全部的引用类型(数组、对象、函数),
__proto__
属性值指向它的构造函数的 prototype
属性值
console.log(obj.__proto__ === Object.prototype);
// true
- 当视图获得一个对象(全部的引用类型)的某个属性时,若是这个对象自己没有这个属性,那么会去它的
__proto__
(即它的构造函数的 prototype
)中寻找。
// 构造函数
function Foo(name, age) {
this.name = name;
}
Foo.prototype.alertName = function() {
console.log('alertName' + this.name);
}
// 建立示例
var f = new Foo('张三');
f.prientname = function() {
console.log('prientname' + this.name);
}
// 测试
f.prientname(); // prientname张三
f.alertName(); // alertName张三
原型链
// 构造函数
function Foo(name, age) {
this.name = name;
}
Foo.prototype.alertName = function() {
console.log('alertName' + this.name);
}
// 建立示例
var f = new Foo('张三');
f.prientname = function() {
console.log('prientname' + this.name);
}
// 测试
f.prientname(); // prientname张三
f.alertName(); // alertName张三
f.toString(); // "[object Object]" 在f.__proto__.__proto__中查找,即Object的显式原型中寻找

instanceof
-
instanceof
用于判断 引用类型
属于哪一个 构造函数
的方法
// f的 __proto__ 一层一层网上找,找到对应的 Foo.prototype
f instanceof Foo //true
f instanceof Object //true
q:如何准确判断一个变量是数组类型
var arr=[]
// 能够正确判断的状况
arr instanceof Array //true
Object.prototype.toString.call(arr) // "[object Array]"
Object.prototype.toString.apply(arr) // "[object Array]"
Array.isArray(arr) // true
// 不能判断的状况
typeof arr // object 是没法判断是不是数组的
// 不许确
arr.constructor === Array //true 可是原型链能够被改写,这样判断不安全
// 扩展 兼容老版本浏览器,isArray的写法
if(!Array.isArray){
Array.isArray = function(arg){
return Object.property.toString.call(arg) === '[object Array]'
}
}
q:写一个原型链继承的例子
function Elem(id) {
this.elem = document.getElementById(id);
}
Elem.prototype.html = function(val) {
var elem = this.elem;
if (val) {
elem.innerHTML = val;
return this; // 后续的链式操做
} else {
return elem.innerHTML;
}
}
Elem.prototype.on = function(type, fn) {
var elem = this.elem;
elem.addEventListener(type, fn);
return this;
}
var main = new Elem('main')
main.html('<p>Hello World</p>').on('click', function() {
alert('Hello javascript')
})
q:描述 new
一个对象的过程
- 建立一个对象
-
this
指向这个新对象
- 执行代码,即对
this
赋值
- 返回
this
function Foo(name, age) {
this.name = name;
this.age = age;
this.class = 'class-1';
//return this ; //默认有这一行
}
var f = new Foo('张三', 22);
var f1 = new Foo('李四', 29);