关于构造函数和原型链运行机制的试题与知识点总结

2024-08-22 03:58

本文主要是介绍关于构造函数和原型链运行机制的试题与知识点总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目:

  • 如何准确判断一个变量是数组类型
  • 写一个原型链继承的例子
  • 描述new一个对象的过程
  • zepto(或其他框架)源码中如何使用原型链

知识点:

1. 构造函数

  • 构造函数要用大写字母开头
  • var a=其实是var a=new Object)的语法糖
  • var a=[]其实是var a=new Array)的语法糖
  • function Foo){…}其实是var Foo=new Function(.)
  • 使用instanceof 可以判断一个函数是否是一个变量的构造函数

a71efaafly1g2rc6awjmxj20mf0dzwhx.jpg

2. 原型规则和示例

  • 所有的引用类型(数组、对象、函数),都具有对象特性,即可自由扩展属性(除了“null"意外)
  • 所有的引用类型(数组、对象、函数),都有一个__proto__(隐式原型)属性,属性值是一个普通的对象
  • 所有的函数,都有一个prototype(显式原型)属性,属性值也是一个普通的对象
  • 所有的引用类型(数组、对象、函数),_proto_属性值指向它的构造函数的"prototype"属性值

a71efaafly1g2rchgklygj20mg0e4dk5.jpg

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

    我们在一个构造函数的显式原型上去定义方法可以有效的减少内存占用,因为如果我们定义在构造函数内部,则每实例化一个对象,就会开辟一个堆内存去存放挂载到其实例上,然而对于方法的调用这是没有必要的

关于 prototype 它有以下几个要点,务必牢记:

  1. 每一个函数(类)都有原型属性,称作prototype,这个属性提供了可供当前类的实例调用的属性和方法。
  2. 浏览器默认给原型开辟的堆内存中有一个constructor属性,这个属性存放的是函数本身
  3. 每一个对象的实例上都有一个__proto__属性称为原型链,这个属性指向当前类的所属原型,不确定的原型都指向Object.prototype,然而Object的__proto__指向null

prototype下的name属性指函数名,length属性指传入的形参的个数

a71efaafly1g2rcm3gp5cj20me0e377t.jpg

利用 for in 循环可以来获取对象身上自己定义的属性而不获取来自原型的属性

a71efaafly1g2rcrpqiwvj20mk0e0tbu.jpg

3. 原型链

当一个方法在原型上没有时,就会查找原型链

a71efaafly1g2rcwekrs7j20mj0du0vy.jpg
a71efaafly1g2rd0r86dzj20mm0drmyo.jpg

4. intanceof

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

finstanceofFoo的判断逻辑是:

  1. f的__proto__一层一层往上,能否对应到Foo.prototype,只要 f.__proto__ == Foo.prototype 就验证通过
  2. 再试着判断 f instanceof Object
function Foo(name) {this.name = name
}
function Foo2() { }var f = new Foo('蔡徐坤');// 让Foo2的prototype指向Foo的prototype,这时候,Foo2与Foo的prototype可以看作为一个对象,也就是说修改Foo的prototype相当于修改Foo1的prototype,反之亦然
Foo2.prototype = Foo.prototype;
Foo.prototype.age = 'unknown';
Foo2.prototype.hobbies = '唱、跳、篮球、Rap';// 由下可以看出Foo2与Foo的prototype指向同一个对象
console.log(Foo.prototype); // Foo { age: 'unknown', hobbies: '唱、跳、篮球、Rap' }
console.log(Foo2.prototype); //Foo { age: 'unknown', hobbies: '唱、跳、篮球、Rap' }// 由于实例 f 的 __proto__ 指向 Foo 的 prototype ,而Foo的 prototype 与 Foo2 的 prototype 是一个,所以 f 既属于 Foo 又属于 Foo2
console.log(f instanceof Foo); // true
console.log(f instanceof Foo2); // true

5. 关于原型重定向问题

先看下面的一个例子:

function fun(){this.a = 0;this.b = function(){alert(this.a);}
}
fun.prototype = {b: function(){this.a = 20;alert(this.a);},c: function(){this.a = 30;alert(this.a);}
}
var my_fun = new fun();
my_fun.b(); // 0
my_fun.c(); // this => my_fun.a = 30 ; 30

结果:0 30

my_fun.a 用来设置私有属性

my_fun.__proto__.a 用来设置公有属性

原型重定向导致的问题:

  1. 自己开辟的堆内存中没有constructor属性,导致类的原型构造函数缺失(解决:自己手动在堆内存中增加constructor属性)
  2. 当原型重定向后,浏览器默认开辟的那个类原型堆内存会被释放掉,如果之前已经存储了一些方法或属性,都会丢失(所以:内置累的原型不允许重定向到自己开辟的堆内存,因为内置类的原型上存在很多属性方法,重定向后都没了,这样是不被允许的;但浏览器对内置类有保护机制)
  3. 当我们需要给类的原型批量设置属性和方法的时候,一般都是让原型重定向到自己创建的对象中

解题:

1. 如何准确判断一个变量是数组类型

var arr = [];
console.log(arr instanceof Array); // true
console.log(typeof arr); // object 不能用typeof判断一个变量是否是数组类型

2. 写一个原型链继承的例子

基础实例:

//动物
function Animal(){this.eat = function(){console.Log('animal eat')}
}
//狗
function Dog(){this.bark = function(){console.Log('dog bark')}
}
Dog.prototype = new Animal()
//哈士奇
var hashiqi = new Dog()
//接下里代码演示时,会推荐更加贴近实战的原型继承示例!

封装DOM查询:戳我查看完整示例代码

function Elem(id) {this.elem = document.getElementById(id);
}Elem.prototype.html = function (html) {if (html == null) {return this.elem.innerHTML;} else {this.elem.innerHTML = html;return this; // 返回this,便于链式操作}
}Elem.prototype.on = function (eventType, fn) {if (eventType != null && fn != null) {this.elem.addEventListener(eventType, fn);return this;} else {throw new Error('请传入“事件类型”,“执行方法”!');}
}var div = new Elem('div');
div.on('click', function(){alert(div.html());
})

3. 描述new一个对象的过程

  • 创建一个新对象
  • this 指向这个新对象
  • 执行代码,即对this 赋值
  • 返回 this (这一步是默认的)

这篇关于关于构造函数和原型链运行机制的试题与知识点总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1095175

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

基本知识点

1、c++的输入加上ios::sync_with_stdio(false);  等价于 c的输入,读取速度会加快(但是在字符串的题里面和容易出现问题) 2、lower_bound()和upper_bound() iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。 iterator upper_bou

2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题是由安全生产模拟考试一点通提供,流动式起重机司机证模拟考试题库是根据流动式起重机司机最新版教材,流动式起重机司机大纲整理而成(含2024年流动式起重机司机证模拟考试题库及流动式起重机司机理论考试试题参考答案和部分工种参考解析),掌握本资料和学校方法,考试容易。流动式起重机司机考试技

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000

状态dp总结

zoj 3631  N 个数中选若干数和(只能选一次)<=M 的最大值 const int Max_N = 38 ;int a[1<<16] , b[1<<16] , x[Max_N] , e[Max_N] ;void GetNum(int g[] , int n , int s[] , int &m){ int i , j , t ;m = 0 ;for(i = 0 ;

两个月冲刺软考——访问位与修改位的题型(淘汰哪一页);内聚的类型;关于码制的知识点;地址映射的相关内容

1.访问位与修改位的题型(淘汰哪一页) 访问位:为1时表示在内存期间被访问过,为0时表示未被访问;修改位:为1时表示该页面自从被装入内存后被修改过,为0时表示未修改过。 置换页面时,最先置换访问位和修改位为00的,其次是01(没被访问但被修改过)的,之后是10(被访问了但没被修改过),最后是11。 2.内聚的类型 功能内聚:完成一个单一功能,各个部分协同工作,缺一不可。 顺序内聚: