console.log(Object.getPrototypeOf(a));{x:1}
a.x = 2;
console.log(a.x); //2
注意:添加的原型属性只能是对象,原始值会报错
检测是否为某个对象的原型
someObj.isprototypeOf(anotherObj)
let c={x:1};
let d=Object.create©;
console.log(c.isPrototypeOf(d));
对象中的super关键字
这个关键字是在ES6中添加的,作用是指向该对象的原型
let obj={
method1(){
return “1a”
}
}
let obj2={
method1(){
return super.method1()
}
}
Object.setPrototypeOf(obj2,obj);
console.log(obj2.method1()); //“1a”
上面这个是类?带学完后补充完整
Object.create(protot[,propertiesObject])
-
protot:原型对象
-
propertiesObject:这是一个数据描述符,这个参数跟Object.definePrototies(obj,props)第二个参数一样
原型链
在JS中,一般而言对象都是继承自Obejct.prototype,包括数组Array
大致就是:a[]继承自Array.prototype,Array.prototype继承自Object.prototype,这个跟作用域链很相似
自定义构造函数
function Person(){}; //构造函数约定俗成首字母大写
Person.prototype.name=“123aaa”;
Person.prototype.y=function(){
return this.name;
}
var person1=new Person();
var person2=new Person();
person1.y(); //123aaa
person2.y(); //123aaa
console.log(person1.y === person2.y); //true
console.log(person1.y === Person.prototype.y); //true
这边可以看出实例化的person1和person2都是继承的Person的原型对象,原型对象被所有实例共享,一旦修改原型对象,那么所有的实例都将会修改
操作对象属性
查询属性
查询属性会沿着对象的原型链一级一级往上查询,直到找到目标或者原型是null的对象为止
function Age() {}
Age.prototype={
name:“john”,
age:23
}
let a1=new Age();
a1.from=“china”;
console.log(a1.age); //23
console.log(a1.from); //china
console.log(a1.toString); //ƒ toString() { [native code] }
这边的a1本身没有age这个属性,当没有时,会去它原型链上的上一级查找,上一级是Age.prototype,找到后返回打印,而后a1本身有form这个属性,因此第二个直接打印,第三个发现自身没有,上一级Age.prototype也没有,就再往上一级Object.prototype上查找;
另外,如果找到最后,在顶层原型上也没有,那么会返回undefined;
添加属性
首先检测对象是否允许添加属性,如果允许,则在原始对象上添加属性或者更改已有属性,添加属性操作不会去修改原型链;
function Age() {}
Age.prototype={
name:“john”,
age:23
}
let a1=new Age();
a1.from=“china”; //这边的from属性只是a1自身的,并不会去修改Age.prototype上的原型
只读属性
function Nav() {}
Nav.prototype={
name:“ulysses”,
age:“28”
}
Object.defineProperty(Nav.prototype,“from”,{
writable:false,
value:‘china’
})
let nav1=new Nav();
nav1.from=“America”;
console.log(nav1.from); //china
上文说了,添加的时候会去检测属性是否在原型链上已存在,并且检测是否可修改,如果不能修改,那么什么都不会发生,另外检测是检测整条原型链,而不是单一某个原型对象,上面的Nav.prototype换成是Object.prototype也是一样的;
属性已存在的情况
function Person(){}; //构造函数约定俗成首字母大写
Person.prototype.name=“123aaa”;
Person.prototype.y=function(){
return this.name;
}
var person1=new Person();
var person2=new Person();
person1.name=“asd”;
console.log(person1.name); //asd
console.log(person2.name); //123aaa
这边可以看出实例化后的属性修改,是相互不影响的,person1的修改没有影响到person2(注意,有一种情况特殊,是数组的push操作,下面会讲)
setter
function Name(){};
Name.prototype={
name1:“aaa”,
name2:“bbb”,
set fullName(value){
let name=value.split(’ ');
this.name1=name[0];
this.name2=name[1];
}
}
let name=new Name();
name.fullName=(“ccc ddd”);
console.log(name.name1);
这个实例设置fullName时,会调用原型上的set方法,会修改原型上的name1和name2
删除属性
delete运算符只能删除对象的自身属性,不能删除从原型继承而来的属性
function Person(){};
Person.prototype.name=“123aaa”;
Person.prototype.y=function(){
return this.name;
}
var person1=new Person();
var person2=new Person();
person1.name=“asd”;
console.log(person1.name); //asd
console.log(person2.name); //123aaa
delete person1.name
console.log(person1.name); //123aaa
console.log(person2.name); //123aaa
检测属性
可以通过in,hasOwnProperty,propertyIsEnumerable等方法来检测属性是否存在
let o={x:1}
in
console.log(“x” in o) //true
console.log(“y” in o) //false
console.log(“toString” in o) //true,会检测整个原型链上的,因此会检测Object.prototype上是否存在
hasOwnProperty
console.log(o.hasOwnProperty(“x”)) //true
console.log(o.hasOwnProperty(“y”)) //false
console.log(o.hasOwnProperty(“toString”)) //false,不会检测整个原型链,只会检测自身是否存在这个属性
propertyIsEnumerable
是hasOwnProperty的增强版,是自身属性,且是可枚举的才返回true
console.log(o.hasOwnProperty(“x”)) //true
console.log(o.hasOwnProperty(“y”)) //false
console.log(Object.prototype.hasOwnProperty(“toString”)) //false,不会检测整个原型链,只会检测自身是否存在这个属性
hasPrototypeproperty
检测原型链是否存在某个属性
console.log(o.hasPrototypeproperty(“x”)) //true
console.log(o.hasPrototypeproperty(“y”)) //false
console.log(o.hasPrototypeproperty(“toString”)) //true,检测整个原型链,是否存在这个属性
总结
=============================================================
从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。
个人将这段时间所学的知识,分为三个阶段:
第一阶段:HTML&CSS&JavaScript基础
第二阶段:移动端开发技术
第三阶段:前端常用框架
-
推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;如果因为我的笔记太过简陋不理解,可以关注我以后我还会继续分享。
-
大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。