JavaScript高级

  • 12. 函数的prototype
  • 13. 显示原型与隐式原型
  • 14. 原型链
  • 15. 原型链属性问题
  • 16. 探索instanceof
  • 17. 面试题
  • 18. 变量提升和函数提升
  • 19. 执行上下文
  • 20. 执行上下文栈
  • 21. 面试题


JavaScript高级部分之函数高级总结,如果有任何问题欢迎讨论或留言

12. 函数的prototype

函数的prototype属性
   每个函数都有一个prototype属性,它默认指向一个Object空对象(即:原型对象)
   原型对象中有一个属性constructor,它指向函数对象

给原型对象添加属性(一般都是方法)
   作用:函数的所有实例对象自动拥有原型中的属性(方法)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>console.log(Date.prototype)//每个函数都有prototype属性console.log(typeof Date.prototype)function Fun (){}console.log(Fun.prototype)console.log(Date.prototype.constructor===Date)//原型对象有一个constructor属性指向函数对象console.log(Fun.prototype.constructor===Fun)Fun.prototype.test = function(){console.log('test')}var fun = new Fun()fun.test()</script>
</head>
<body></body>
</html>

13. 显示原型与隐式原型

每个函数function都有一个prototype即显式原型(属性)
每个实例对象都有一个__proto__即隐式原型(属性)
对象的隐式原型的值为其对应构造函数的显示原型的值

总结:函数prototype属性在定义函数时自动添加的,默认值是一个空Object对象
   对象__proto__属性在创建对象时自动添加的,默认值为构造函数的prototype属性值
   程序员只能操作显式原型,不能直接操作隐式原型(ES6之前)

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>function Fn (){//内部语句:this.prototype = {}}console.log(Fn.prototype)//每个函数都有一个prototype即显式原型,默认指向一个空的Object对象var fn = new Fn()//内部语句:this.__proto__=Fn.prototypeconsole.log(fn.__proto__)//每个实例对象都有一个__proto__即隐式原型console.log(Fn.prototype===fn.__proto__)//trueFn.prototype.test = function (){//给原型对象添加方法console.log('test')}fn.test()//通过实例对象调用原型对象的方法</script>
</head>
<body></body>
</html>

14. 原型链

访问一个实例对象中的属性时,先在自身属性中查找,找到返回
如果没有,再沿着__proto__这条链上查找,找到返回
如果最终没有找到,返回undifined

原型链别名隐式原型链
  作用:查找对象的属性(方法)

所有函数的__proto__都是一样的,都是Function创造函数的显示原型的值

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>function Fn (){this.test1 = function (){console.log('test1()')}}Fn.prototype.test2 = function (){console.log('test2()')}var fn = new Fn()fn.test1()fn.test2()console.log(fn.toString())fn.test3()//报错,fn.test3 is not a function</script>
</head>
<body></body>
</html>

补充:函数的显示原型指向的对象默认是空的Object实例对象(但是Object不满足)
    所有函数都是Function的实例(包括Function本身)
    Object的原型对象是原型链的尽头,其隐式原型值为null
    Function的显示原型和隐式原型指向同一对象

console.log(Fn.prototype instanceof Object)//trueconsole.log(Object.prototype instanceof Object)//falseconsole.log(Function.prototype instanceof Object)//trueconsole.log(Function.__proto__ === Function.prototype)//trueconsole.log(Object.prototype.__proto__)//null

15. 原型链属性问题

读取对象的属性值时:会自动到原型链中查找
设置对象的属性值时:不会查找原型链,如果当前对象没有此属性,直接添加并设置其值
方法一般定义在原型中,属性一般通过构造函数定义在对象本身上

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>function Fn (){}Fn.prototype.a = 'zhangsan'var fn1 = new Fn()console.log(fn1.a,fn1)var fn2 = new Fn()fn2.a = 'lisi'console.log(fn1.a,fn2.a,fn2)function Person(name,age){this.name = namethis.age = age}Person.prototype.setName = function(name){this.name = name}var p1 = new Person('wangwu',20)p1.setName('laoliu')console.log(p1.name,p1.age)var p2 = new Person('daxiong',22)p2.setName('jingxiang')console.log(p2)console.log(p1.__proto__ === p2.__proto__)//true</script>
</head>
<body></body>
</html>

16. 探索instanceof

instanceof如何判断的?

表达式:A instanceof B
   如果B函数的显示原型对象在A对象的原型链上,返回true,否则返回false

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>function Foo(){}var f1 = new Foo()console.log(f1 instanceof Foo)//trueconsole.log(f1 instanceof Object)</script>
</head>
<body></body>
</html>

17. 面试题

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>//面试题1var A = function (){}A.prototype.n  = 1var b = new A()A.prototype = {n:2,m:3}var c = new A()console.log(b.n,b.m,c.n,c.m)//1 undifined 2 3 //面试题2var F = function (){ }Object.prototype.a = function (){console.log('a()')}Function.prototype.b = function (){console.log('b()')}var f = new F()f.a()// f.b() //报错F.a()F.b()console.log(F.prototype)</script>
</head>
<body></body>
</html>

【注意】对于第一个问题令A.prototype指向一个新对象,则会改变后面创建实例对象隐式原型的指向,但对前面创建的实例对象没有影响
    对于第二个问题原型链可以参照上文16图

18. 变量提升和函数提升

变量声明提升
   通过var定义(声明)的变量,在定义语句之前就可以访问到
   值:undifined

函数声明提升
   通过function声明的函数(必须声明的方式,不能是表达式),在之前就可以直接调用
   值:函数定义(对象)

先执行变量提升在执行函数提升

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>var a = 3function fun (){console.log(a)var a =4}fun()console.log(b)//undifined 变量提升fun2()//可调用  函数提升fun3()//报错,不能调用 变量提升 var b = 3function fun2 (){console.log('fun2')}var fun3 = function (){console.log('fun3')}</script>
</head>
<body></body>
</html>

19. 执行上下文

代码分类:
   全局代码
   函数代码(局部代码)

全局执行上下文
   在执行全局代码之前将window确定为全局执行上下文
   对全局数据进行预处理
     用var定义的全局变量–>undifined,并添加为window属性
     function声明的全局函数–>赋值(fun),并添加为window的方法
      this–>赋值(window)
   开始执行全局代码

函数执行上下文
   在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象(不真实存在)
   对局部数据进行预处理
     形参变量–>赋值(实参)–>添加为执行上下文的属性
     arguments–>赋值(实参列表),并添加为执行上下文的属性
     var定义的局部变量undifined,并添加为执行上下文的属性
     function声明的函数–>赋值(fun),并添加为执行上下文的方法
     this–>赋值(调用函数的对象)
   开始执行函数体代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>console.log(a1,window.a1)window.a2()console.log(this)var a1 = 3function a2(){console.log('a2()')}console.log(a1)console.log('-------------------')function fn (o1){console.log(o1)//2console.log(o2)//undifinedo3()//o3()console.log(this)//windowconsole.log(arguments)//伪数组(2,3)var o2 = 3function o3(){console.log('o3()')}}fn(2,3)</script>
</head>
<body></body>
</html>

20. 执行上下文栈

在执行全局代码之前,JS引擎会创建一个栈来存储管理所有的执行上下文对象
在全局执行上下文(window)确定后,将其添加到栈中(压栈)
在函数执行上下文创建后,将其添加到栈中(压栈)
在当前函数执行完后,将栈顶的对象移除(出栈)
当所有代码执行完后,栈中只剩window

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>var a = 10var bar = function (x){var b = 5foo(x + b)}var foo = function (y){var c = 5console.log(a + c + y)}bar(10)</script>
</head>
<body></body>
</html>

21. 面试题

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>//面试题1,共产生了5个执行上下文:4个foo和1个windowconsole.log('global begin:' + i)//undifinedvar i = 1//变量提前foo(1)//函数提前function foo (i) {if(i == 4){return;}console.log('foo() begin:' + i)//1 2 3foo(i+1)//递归调用console.log('foo() end:' + i)//3 2 1}console.log('global end:' + i)//1//面试题2,先执行变量提升在执行函数提升function a (){ }//函数提升var a //变量提升console.log(typeof a)//'function'//面试题3if(!(b in window)){//window没有b属性,falsevar b = 1}console.log(b)//undifined//面试题4var c = 1function c (c){console.log(c)}c(2)//报错,c不是函数/*等价于:var cfunction c (c){console.log(c)}c = 1c(2)*/</script>
</head>
<body></body>
</html>

JavaScript高级(二)相关推荐

  1. javaScript高级[二]

    javaScript高级[二] 函数 函数的定义和调用 函数的定义方式 函数的调用方式 this 函数内this指向 改变函数内部this指向 call()方法 apply()方法 bind()方法 ...

  2. JavaScript高级(二)|函数进阶+正则表达式

    一.函数进阶 01.函数的定义与调用 1.1函数的定义方式 1.2函数的调用方式 02.this 2.1函数内this的指向 2.2改变函数内部this的指向 2.3 call apply bind总 ...

  3. JavaScript 高级编程(二)

    JavaScript 高级编程(二) BOM 一套操作浏览器的API. 常见对象 window: 代表整个浏览器窗口 注意: window是BOM中的一个对象, 并且是一个顶级的对象(全局) Navi ...

  4. 【读书笔记】JavaScript高级编程(二)

    2019独角兽企业重金招聘Python工程师标准>>> 书中第3章 基本概念摘要(一) 3.3 变量 使用var操作符定义的变量将成为定义该变量的作用域中的局部变量.也就是说,如果在 ...

  5. 《JavaScript高级程序设计(第3版)》教程大纲

    词条 <JavaScript高级程序设计>是2006年人民邮电出版社出版的图书,作者是(美)(Nicholas C.Zakas)扎卡斯.本书适合有一定编程经验的开发人员阅读,也可作为高校相 ...

  6. 前端红宝书《JavaScript高级程序设计》核心知识总结

    此文是对<JavaScript 高级程序设计>一书难点的总结,也是笔者在看了 3 遍之后的一些梳理和感想,希望能借此巩固js的基础和对一些核心概念有更深入的了解. 摘要 JS基本的数据类型 ...

  7. 攻下《JavaScript高级程序设计》——第二章 在HTML中使用JavaScript

    从上一章我们知道了,JavaScript是一种专门为网页交互而设计的脚本语言,那么,它就免不了和HTML打交道,所以在设计JavaScript的时候,Netscape首要面临的就是,怎么让HTML和J ...

  8. 《javascript高级程序设计》笔记:变量对象与预解析

    上一篇:<javascript高级程序设计>笔记:内存与执行环境 上篇文章中说到: (1)当执行流进入函数时,对应的执行环境就会生成 (2)执行环境创建时会生成变量对象,确定作用域链,确定 ...

  9. javascript 高级程序设计_JavaScript 经典「红宝书」,几代前端人的入门选择

    人的一生中总要读几本经典书,在这个"经典"泛滥的年代,什么才是权威的代表,我想大概是一本的书的口碑,能积累下上佳口碑的书,往往也是能经得住时间推敲的.比如这本: 相信许多前端开发者 ...

  10. JavaScript高级篇之Function对象

    JavaScript高级篇之Function对象 一: Function对象引入: Function对象是js的方法对象,可以用Function实例化出任何js方法对象. 例如: 1 <%@ p ...

最新文章

  1. COBOL入门到精通
  2. Linux中shell模块的考试,linux下的shell编程要考试了题目这里有可是表示不会 求帮忙...
  3. PHP实现页面跳转的几种方法
  4. 云原生时代, 选择.NET Core
  5. JavaScript学习随记——属性类型
  6. 同一Inputstream的父类和子类对象请维持最具体的子类对象,不要混合使用
  7. 进制转化(北理乐学编程题目)
  8. 吉米多维奇数学分析习题集每日一题--泰勒公式习题1378
  9. Android 权限的一个类型系统模型
  10. linux heartbeat rpm,Heartbeat 3.0.3 介绍及rpm
  11. 如何用计算机自动求和,如何在excel中自动求和 自动求和的解决方法及步骤
  12. Dropbox 架设免费个人网站
  13. python制作飞机大战游戏准备工作相关知识点
  14. 基于Java的Socket实现TCP连接
  15. 46.QDateTimeEdit
  16. python 循环播放音乐_pyaudio:基于pyaudio利用Python编程实现播放音频mp3、wav等格式文件...
  17. 闪电的驯服者:电学的历史
  18. Struts2-----面试题汇总
  19. Linux基础学习(Ubuntu)
  20. MEM/MBA英语基础(09)倒装句

热门文章

  1. bandizip修改压缩文件内容_BandiZip解压添加压缩文件教程
  2. Connectionist Temporal Classification: Labelling Unsegmented Sequence Data with Recurrent Neural Netw
  3. Maven Failsafe 插件
  4. 2023计算机考研专业课参考书目(408)
  5. windows下搭建自己的跨平台tts语音合成播报技术
  6. HTML5基本标签使用header,nav和footer
  7. 网站关键词选择的四大步骤
  8. PHP QQ网页三方登录
  9. 区块链入门导航-磨链社区
  10. EPLAN插入符号为空的解决方法