• JS第一周学习笔记整理


    JS正式课第一周笔记整理

    • webstorm : 代码编辑器
    • 浏览器: 代码解析器;
    • Git : 是一个工具;用于团队协作开发项目管理代码的工具;在工作中用git、svn
    • svn : 集中式;
    • 集中式:需要一个中央服务器;每次开发前需要从中央服务器把最新的代码拉取下来,然后进行开发;并且需要网络;
    • git : 分布式;
    • 分布式:每个人的电脑都是一个中央服务器;不需要网络也可以进行提交代码;

    DOS命令

    • 1.按着shift右键,在此处打开powerShell
    • 2.找到相应的文件夹,直接输入cmd,按回车;
    • window+r : 输入cmd

    切换磁盘路径

    • cd + 文件夹名字: 打开相应的路径
    • cd ../ : 回到上一级
    • cd / : 回到跟路径;
    • mkdir + 文件名字 : 创建文件夹
    • cls : 清除所有的命令

    Git

    配置Git用户名和密码
    • git config --global user.email "邮箱"
    • git config --global user.name "用户名"
    Git的简单命令
    • git init : 初始化一个git 仓库(生产.git文件)
    • git add . : 把所有文件提交到暂存区
    • git add [文件名]:推送指定的文件到暂存区
    • git commit -m"注释" : 把代码提交到历史区;(推送到历史区之后Git会自动分配一个版本号xxxxxx,根据版本号可以回到任何一次修改的位置)
    • git status:查看文件状态;如果文件只存在本地,不在暂存区,那么颜色是红色,如果文件在暂存区还没有提交到历史区,那么颜色是绿色
    • 本地代码- ->暂存区- ->历史区
    本地仓库与远程仓库通信
    • git remote add origin(仓库名) url地址:将本地仓库与远程仓库建立连接
    • git remote -v:查看本地仓库和远程仓库关联状态
    • git push origin(与建立连接时的仓库名一样) master(主分支名):将历史区内容推送到远程仓库
    • git config --list:查看本地配置环境
    • 输入用户名和密码
    推送过程(详细步骤)
    本地操作
    • ① git init(初始化git仓库)
    • ② git add .(将文件推送到暂存区)
    • ③ git status(查看文件状态)
    • ④ git commit -m "注释"(将代码提交到历史区,并添加注释)
    远程仓库操作
    • git remote add origin(仓库名) url地址
    • git remote -v
    • git push origin(仓库名) master
      Alt text
    推送复原过程

    Alt text

    拉取克隆过程(详细步骤)
    • git clone 仓库地址url:这里已经是一个git仓库,并且已经和远程建立和连接
    • git pull origin master:拉取远程仓库代码
      Alt text

    GitHub

    • GitHib:是一个开源网站,可以供大家分享代码 插件和框架
    • 把本地的代码提交到远程仓库(GitHub)
    • 让本地仓库和远程仓库进行绑定

    作用域

    作用域:代码执行的空间环境 ===栈内存

    浏览器的渲染机制:先形成一个DOM树和CSS树,最后两个树合成render树

    全局作用域 : 当打开浏览器时,浏览器会形成一个全局的作用域,给当前代码提供运行环境的;并且存储基本数据类型值;

    • 存储基本数据类型值
    • 基本数据类型存储到栈内存中,全局作用域是最大的一个栈内存
    • window是全局中最大的一个对象,存储了大量的内置属性

    私有作用域:一个函数执行的时候就会形成一个私有作用域,函数执行完成(或关闭浏览器)就销毁
    块级作用域:ES6新增的,除了私有作用域和对象以外所有被一个{}包裹起来的,(三个判断,三个循环)eval("({a:1})")、for 循环中用let ,会形成父作用域;每循环一次,都会形成一个子作用域;在子作用域中会把当前的i进行保存

    全局变量:在全局作用域下定义的变量
    • 会给window新增一个键值对
    • 全局下定义的函数相当于给window新增键值对,属性名是函数,属性值是整个函数
    私有变量:
    • 在函数体中被var 、function、const、let声明
    • 函数的形参也是私有变量
    性能优化
    //1-
    function fn(){
    //传入任意参数求和
    	var total = 0;
    	var len = arguments.length;
    //(var i = 0;i<arguments.lenth;i++)
    	for(var i = 0;i<len;i++){
    		var cur = arguments[i];
    		if(!isNaN(cur)){
    		//total += arguments[i];
    		total += cur;
    		}
    	}
    }
    //2- in 方法用于检测对象中是否有该属性
    function fn(){}
    console.log('fn' in window);//true
    //'fn'必须加引号,不叫引号就是这个变量对应的值
    
    //3-
    var a,b,fn = function(){
    	var a = b = 10;
    	//(var a = b = 10;-->var a = 10;b = 10;)
    	//a变成了局部变量无法修改外部,b是全局变量,修改了外部
    }
    fn();
    console.log(a,b);//undefined 10
    

    变量提升

    https://blog.csdn.net/zjy_android_blog/article/details/80863425

    https://blog.csdn.net/longwenjunjie/article/details/48163293

    变量提升的定义

    变量提升:在作用域形成之后代码执行之前,将所有带var和function关键字的变量提前声明或定义

    JS可以在浏览器中农运行 是因为浏览器给JS提供了赖以生存的环境,这个环境就是作用域

    • var:只是提前声明;默认值是undefined
    • function:既声明又定义
    • debugger:打断点

    形成作用域-变量提升-代码从上到下执行

    变量提升的特殊情况
    • 不管条件是否成立,都要进行变量提升
    • 条件判断中的函数,在条件判断之前,带var和带function都只是声明不定义
    • 当条件成立之后,第一件事就是给函数复制;
    • 条件不成立,判断体就不执行,结合ES6的块级作用域
    • 如果不带var直接赋值就相当于给window直接添加了一个属性 并且给它赋值
    • var就相当于子安全局作用域下增加了一个属性,还给全局对象window增加了一个属性
    • 注意: 带var 的可以不赋值,但是也相当于给全局对象window增加了一个属性. 不带var的必须要赋值,否则就会去找全局对象window上是否有这个属性,没有这个属性就会报错.
    • 用逗号分隔的表示连var;如:var a = 1,b = 2,c = 3;
    • 用分号(分号代表代码段)来分隔的,前面带var的属于变量,不带var的相当于给全局对象window添加了属性;如:var a = 1;b = 2;c = 3;
    • 连等 带var的是一个变量,其他的不带var的就相当于给全局对象window添加了属性
    • 变量提升只发生在=左边
    • return后面的内容不进行变量提升 但是下面的 代码要进行变量提升
    function f3(){
    	console.log(f4());//打印f3函数体中的内容
    	console.log(f2());//报错f2没有进行变量提升
    	return function f2(){
    	//return 后面的内容不进行变量提升 但是下面的代码要进行变量提升
    	}
    	function f4(){
    		console.log(f3);
    	}
    }
    f3();
    
    
    var a = [1];
    b = a;
    b[1] = 'a';//b = [1,'a']
    console.log(a);//[1,'a'] b指向了a的地址,修改的时候修改了地址中的属性以及属性值
    
    • 变量名重复:不再进行声明,但是要重新定义 (函数名跟变量名重复取函数名、函数名和函数名重复会覆盖)
    • 函数当做参数的时候,不进行变量提升
    • 匿名函数不进行变量提升
    • 自执行函数不会进行变量提升
    • let const声明的变量不进行变量提升

    函数的定义与执行

    • 定义的三步曲:
    • 开辟新的堆内存
    • 存储代码字符串
    • 返回内存空间地址
    • 函数执行过程:
    • 首先会形成一个私有作用域,开辟一个栈内存
    • 形参赋值
    • 变量提升
    • 代码从上到下执行
    • 作用域是否销毁
    • 对象的定义:
    • 开辟一个空间地址,堆内存
    • 把键值对存储到堆内存下
    • 把空间地址赋值给对象名
    console.log(fn);//fn()
    console.log(f);//undefined
    function fn(){}//函数声明和定义
    var f = function(){}//函数表达式-->箭头函数
    
    console.log(fn);//fn函数体
    console.log(f);//undefined
    console.log(fn());//打印两次undefined 函数执行的时候打印f为undefined,并且函数没有返回值 打印一次undefined
    function fn(){
    console.log(f);
    }
    var f = function(){}//函数声明
    
    console.log(f2);//f2未定义 报错
    var 
    var f = function f2(){}
    console.log(f2)//f2未定义 报错
    setTimeout(funtion f2(){},1000)//函数作为参数的时候不进行变量提升
    

    函数声明提升

    1、函数的两种创建方式
    • 函数声明
    • 函数表达式

    函数声明的语法

    f('nihao');
    function f(name){
    	console.log(name);
    }
    //能打印出nihao
    

    函数表达式语法

    f('nihao');
    var f = function (name){
    console.log(name);
    }
    //控制台报错 Uncaught ReferenceError:f id not function错误显示f不是一个函数
    

    两种方式的区别:

    • 函数声明又一个非常重要的特征:函数声明提升,函数声明语句将会被外部脚本或者外部函数作用域的顶部(跟变量提升非长相似)。正是这个特征,所以可以把函数声明放在调用它的语句后面。
    var getName = function (){
    console.log(2);
    }
    function getName(){
    console.log(1);
    }
    getName();
    //打印出2
    

    这个例子涉及到了变量声明提升函数声明提升.正如前面提及到的函数声明提升,函数声明function getName(){}的声明会被提前到顶部.而函数表达式var getName = function(){}则表现出变量声明提升.因此,在这种情况下,getName也是一个变量,这个变量的声明将被提升到底部,而变量的赋值依然保留在原来的位置.需要注意的是:函数优先,虽然函数声明和变量声明都会被提升,但是函数会首先被提升,然后才是变量。因此上面的函数可以换成这个样子

    function getName(){
    //函数声明提升到顶部
    console.log(1);
    }
    var getName;//变量声明提升
    getName = function(){
    //变量赋值依然保留在原来的位置
    console.log(2);
    }
    getName();//最终输出2
    

    在原来的例子中,函数声明虽然是在函数表达式之后,但是由于函数声明提升到顶部,因此后面getName又被函数表达式的赋值操作给覆盖了,所以控制台输出了2
    Alt text
    Alt text

    console.log(f);//打印函数体
    function f(){
    	console.log(1);
    }
    f();//88
    function f(){
    	console.log(2);
    }
    function f(){
    	console.log(3);
    }
    f();//88
    f = 99;
    function f(){
    	console.log(88);
    }
    f();//f is not a function 
    console.log(f);
    

    ES6的let和const

    var 与ES6中const 、let声明的变量的区别
    https://blog.csdn.net/qq_22855325/article/details/72843456

    let不能和函数重名

    • const声明的变量,
    • 如果是基本数据类型,那么不可以进行数据修改.
    • 如果 是引用数据类型值,就可以操作引用地址,不可以替换引用地址
    • 没有变量提升
    • 不可以重复声明
    • 定义的变量不会给window增加属性
    • 定义的是个常量,定义之后不可以修改
    • 一旦声明必须赋值
    • let虽然不会进行变量提升,但是会先检查当前作用域下是否有重复命名
    • 没有变量提升
    • 不可以重复声明
    • 定义的变量不会给window增加属性
    var a = 2;
    if('a' in window){
    	console.log(a);//形成暂时性死区,即在块级作用域下,不能提前拿到let声明的变量的值,打印2
    	let a = 1;
    }
    
    let

    ES6中提出了一个新的变量,不在于取代var,而在于解决ES5中var声明中的一些痛点;这就是let
    let的特点

    • 1、let是块级变量,不存在于window下[非全局属性],window,变量名是找不到的,它的作用范围就那么一小块
    • 2、let不允许重新声明同名变量,会抛出异常,具有唯一性
    • 3、let不允许没声明就使用,会抛出异常,只有执行该声明的时候才能使用
    • 4、let有自己特色的闭包特性,比如在for循环的应用中
    //1-
    let tt = 'nihao';
    console.log(tt);//打印出'nihao'
    console.log(window.tt);//打印出undefined
    
    //2-
    function test2(){
    	var abc = 99;
    	let abc = 88;
    	console.log(abc);
    }
    test2();//打印值:Uncaught SyntaxError:Indentifier 'abc' has already been declared
    
    //3-
    function test3(){
    	console.log(test3);
    	let test3 = '哈哈哈哈';
    }
    test3();//打印值:Uncaught ReferenceError:test3 is not defined
    
    //4-每一次for村换都重新绑定一次作用域且脱离失效,就是let自身的特色
    for(let i = 0;i<9;i++){
    	//for循环形成保护机制
    	console.log('循环内的值是:'+i);
    }
    console.log(i);//打印值
    //循环内的值是:0
    //循环内的值是:1
    //循环内的值是:2
    //循环内的值是:3
    //循环内的值是:4
    //循环内的值是:5
    //循环内的值是:6
    //循环内的值是:7
    //循环内的值是:8
    //Uncaught ReferenceError:i is not defined  块级作用域 外界无法访问
    

    查找上一级的作用域

    1、在当前作用域下输出变量值时,首先观察是否是私有变量

    • 如何判断一个变量是私有的
    • 当前变量有没有被var过和function
    • 形参也是私有变量

    2、如果变量不是私有的,就向上一级作用域查找

    • 上一级作用域判断函数在哪定义的,函数上一级的作用域就是谁,跟函数执行没有任何关系
    • 但获取变量值时,首先是否是私有变量,如果不是就向上一级作用域查找,一级一级向上,直到window为止,如果window也没有,那么就会报错,这样一级一级向上查找作用域就是作用域链

    堆内存的销毁

    形成两个虚拟内存:栈内存、堆内存
    栈内存:作用域
    引用数据类型
    在JS中的{}[]都是开辟一个新的空间地址
    谷歌浏览器:每隔一段时间,自动检查占用并是否销毁
    火狐和IE:采用的计数的规则,当堆内存地址被占用一次时,计数+1,否则-1,如果是被占用0次,就回收

    私有作用域的销毁

    • 函数的执行:形成一个私有的作用域,提供代码运行环境,存储基本数据类型
    闭包
    • 保护里面的私有变量不受外界干扰
    • 存储值
    • 保护机制:当前私有作用域中,有引用数据类型被外界所占有,导致当前作用域变成一个不销毁的作用域,里面的变量就成了不销毁的变量

    一般情况下,函数执行完成之后,当前作用域就会销毁
    函数没执行一次就会开辟一个新的私有作用域,并且新的私有作用域和之前的作用域没有任何关系,是两个不同的栈内存

    • 不销毁的作用域:
    • 函数执行return出一个引用的数据类型值
    • 函数执行return出的引用数据类型值并且被外界接收(被占用)

    栈内存

    浏览器加载的时候,碰到引用数据类型,都会开辟一个新的内存空间,[对象:键值对;函数:代码字符串],给这个内存空间赋一个16进制内存地址,将这个内存地址指向声明的变量,这个内存空间就是堆内存
    堆内存的释放,手动赋值null,[指向空指针];浏览器判断该内存没有变量就去收回它,就会释放

    function fn(){
    	var t = 10;
    	return function (){
    		console.log(t++)
    	}
    }
    var f = fn();
    f();
    f();
    
    • 不立即销毁:
    • 需要等到里面的小函数执行完成之后,那么外层作用域就会销毁
    function fn(){
    	var t = 10;
    	return function (){
    		console.log(t++);
    	}
    }
    fn()();
    
    var i = 0;
    function fn(){
    	//i = 5 6;
    	return function(n){
    		console.log(n + i++);
    	}
    }
    var f = fn(5);
    f(10);//15
    f(20);//26
    fn(8)(12);//20
    fn()(18);//NaN
    
    function fn (){
    var a = 1 ;
    return function (){
    a++;
    console.log(a);
    }
    }
    var f = fn();
    f(); //2
    fn()(); //2
    f(); //3
    
    var obj= {
     i : 10,
    fn:(function () {
    var i = 0;
    return function (n) {
    console.log(n + i++)
    }
    })()
    };
    var f = obj.fn;
    f(10);// 10
    f(20);// 21
    obj.fn(30);// 32 块级作用域
    obj.fn(40);// 43
    

    this关键字

    • 函数中的this,指的就是函数的当前执行主体
    • 1、在全局作用域下,this 指向window
    • 2、函数体中的this,看函数执行前有没有'.';如果有,那么'.'前面是谁,this就指向谁;如果没有'.',那么会指向window
    • 3、如果给元素的事件行为绑定方法,,那么方法中的this,就会指向当前被绑定的那个元素
    • 4、回调函数中的this指向window
    • 5、自执行函数中的this一般都指向window
    • 6、forEachmap第二个参数可以修改回调函数中的this
    • 7、构造函数中的this指向当前类的实例
    • 8、call、apply、bind可以改变this关键字的指向
    • this是谁,和它在哪定义的以及在哪执行的没有任何关系
      Alt text
      Alt text
      Alt text
    function b() {
    	console.log(this); //window
    }
    window.b();
    var obj = {
    	num:1,
    	fn : function () {
    		console.log(this);
    		function m() {
    			console.log(this);// window;
    		}
    		m()
    	}
    }
    var f = obj.fn;
    f(); // window
    obj.fn();// obj
    var obj = {
    	num:1,
    	f:{
    		num:2,
    		fn:function () {
    		console.log(this);// obj.f
    		}
    	}
    }
    obj.f.fn()
    
    //1.
    setInterval(function () {
    	console.log(this); // window
    },1000)
    //2.
    (function () {
    	console.log(this); //window
    })()
    //3.
    var obj = {
    	fn: (function () {
    		console.log(this); //window
    })()
    }
    
    var num =2;// 1 2
    var obj = {
    	num : 0,
    	fn : function () {
    		num = 1;
    		// this-->obj
    		(function (num) {
    		// this --> window
    			++this.num;
    			num++;
    			console.log(num)// 1
    		})(this.num)// 0
    	}
    }
    obj.fn();
    console.log(window.num,obj.num) //2 0
    

    this的重点练习题

    var num =2;// 1 2
    var obj = {
    	 num : 0,
    	 fn : function () {
    	 num = 1;
         // this-->obj
    	(function (num) {
    	// this --> window
    		++this.num;
    		num++;
    		console.log(num)// 1
    	})(this.num)// 0
      }
    }
    obj.fn();
    console.log(window.num,obj.num) //2 0
    

    Alt text
    Alt text

    设计模式-单例模式

    模块化开发

    把一个项目按照页面或者功能分割成不同的任务,交给项目中不同的成员开发.开发结束之后
    将代码合并到一起.

    • 多人协作开发的问题: 变量名 函数名 冲突
    • 为了防止全局变量污染: 闭包但是闭包并不完美,所以选择搭配设计模式来进一步进行
      项目开发
    单例模式
    • 表现形式:就是一个对象:{name:xxx,age:function(){}};
    • 定义:把描述同一件事物的不同属性放在同一个对象[空间]下,避免了全局变量的干扰;这种模式就是单例模式
    • 在设计模式当中,这个person不仅仅是一个对象名,还是一个命名空间,多个命名空间是相互独立的,互不干扰
    • 好处:不受全局变量的污染和干干扰,并且可以相互调用方法
    • 由来:单例模式的本质就是一个对象,它是object类上的一个实例,实例与实例之间互不干扰,叫做单独的实例,简称"单例"
    高级单例模式
    • 定义:在高级单例模式当中,我们不只会把一个对象赋值给一个命名空间,我们会先让它执行一个自执行函数,[就形成了一个闭包,一个不销毁的作用域],在自执行函数中,返回一个对象给这个命名空间
    • 好处:可以在私有的作用域当中,创建很多的属性和方法,仅需要把我们使用的属性和方法暴露在这个对象当中即可。相对于单例模式,可以存储不同方法中的公有变量
    工厂模式
    • 定义:把实现同一种功能的代码放进一个函数中,当想实现类似功能时,只需要执行这个函数即可,传参数不同就可以.
    • 好处:减少了代码的冗余:"高内聚、低耦合"-->函数的封装

    面向对象

    • OOP/OP面向对象的缩写,面向对象思想
    • 定义:面向对象的封装、继承和多态,通过简单的实例化,调用其他的方法和属性
    • JS就是通过面向对象的思想设计开发出来的
    • 需要了解 对象、类、实例
    • 对象:万物皆对象,多为一种泛指,可以是任何物体
    • 类:对象中具有同一属性和特征的集合,类又分为大类和小类
    • 实例:就是类中的一个具体的细分,我们研究当前实例具有哪些属性和方法,那么证明当前类中的其他实例也同样具有
    JS中的内置类
    • JS中的任何数据类型都是它所属的类,除了null、undefined
    • Number、String、Boolean、Object、Array RegExp、Function、Date...
    • 类的首字母都是大写
    • 类的执行通过new来执行
    • Object对象类,被称为基类,在任何数据类型都可以通过__proto__[原型链]找到基类Object
    创建类
    • 字面量方式
    • 实例化方式
    • 引用数据类型方式创建 var ary = new Array('1')
      注意:
    • new Array(10):创建一个长度为10的数组,数组中的每一项都是空
    • new Array('10'):如果只传递一个实参,并且实参不是数字,相当于把当前值作为数组的第一项存储进来
    • new Array(10,20,30):如果传递多个实参,不是设置长度,而是把传递的内容当做数组中的每一项存储起来
    构造函数
    • 定义:当一个函数通过new关键字来执行的时候,这个函数就不是普通函数了,它是一个构造函数,也是一个自定义类,当前的函数名就是类名,这个函数的返回值就是这个类的实例
    • 为了让构造函数和普通函数有一个区别,我们建议写构造函数的时候首字母大写[类名]
    • 注意:一般情况下,我们写业务逻辑的时候不会用到构造函数,但是在封装库、插件以及组件的时候就会用到构造函数模式
    • 构造函数执行的时候,如果没有参数的时候,小括号可以不写
    • let person = new Person
    普通函数和构造函数的区别
    • 相同点:形成私有的作用域-->形参赋值-->变量提升-->从上到下执行-->作用域销毁
    • 不同点:
      • 构造函数运行时,形成作用域后,在代码运行之前,首先会给当前的作用域初始化一个空对象;并且让当前作用域下的this指向这个空对象 当代码运行结束,构造函数把函数体中的this作为返回值返回
      • 构造函数如果并不需要传参,可以省略执行的小括号
      • 构造函数中的this,指向当前的实例
      • 在构造函数中,return 一个基本数据类型值,那么对实例没有任何影响;如果return出一个引用数据类型值,那么会把默认returnthis替换掉.
    构造函数的执行过程
    • 形成一个私有的作用域
    • 形参赋值
    • 变量提升
    • 浏览器会创建一个对象,[开辟一个新的堆内存],将这个对象指向了this[堆内存指针指向this实例]
    • 代码从上到下执行
    • 判断当前构造函数是否有return,
    • 如果没有return默认将实例返回;
    • 如果有return,
      • 如果return的是基本数据类型,对实例没有影响
      • 如果是引用数据类型,那么实例就是该引用数据类型
    • 构造函数中:建议不要轻易return引用数据类型
      Alt text
    私有属性
    • 在构造函数中,给this添加属性值和方法,都属于当前实例的私有属性
    公有属性
    • 当前实例通过__proto__找到所有的属性和方法都输属于当前实例的公有属性
    • 实例想要调取公有属性,直接可以调取,底层及时通过__proto__去找这个属性
    • 用in这种方式来判断,当前属性名[公有属性+私有属性]是都属于这个对象
      console.log('hasOwnProperty' in person1);
    • Object类提供一个hasOwnProperty,这个方法判断当前属性是否是该实例的私有属性:返回布尔值console.log(person1.hasOwnProperty("age")) //true console.log(person1.hasOwnProperty("valueof")) //false
      例题:自己封装一个方法,判断当前属性是否是当前实例的一个公有属性hasPubProperty
    function hasPubProperty(obj,item){
            //先检测是否是属性
            return item in obj &&!obj.hasOwnProperty(item);
        }
        console.log(hasPubProperty([], 'toString'));
    
    JS中的函数
    • 普通函数、类(自定义类和内置类)、函数类的实例
    对象
    • 普通对象(对象数据类型)
    • 构造函数new出来的一个实例,也是一个对象
    • 类上面的原型也是一个对象
    • 函数也是一个对象
    学习原型模式需要记住三句话
    • 所有的函数都天生自带一个属性,叫做prototype(原型),它是一个对象,既然是对象,那就是一个堆内存

    • 所有函数的原型上面(都是开辟的这个堆内存),都天生自带一个属性,叫做constructor(构造函数),它指向当前类本身

    • 所有的对象都天生自带一个属性__proto__,它指向当前类的原型

    • 所有的函数数据类型(普通函数、类(内置的、自定义))都是Function的一个实例;Function是所有函数的基类;

    • 5.所有的对象数据类型(实例、prototype、对象)都是Object的一个实例;Object是所有对象数据类型的基类;

    • Function 首先是自己的一个实例;
      Alt text

    function People(name){
    	let age = 9;
    	this.name = name;
    	this.age = age;
    }
    People.prototype.say = function () {
    	console.log(this);
    };
    let person1 = new People('zf');
    let person2 = new People('zhufeng');
    //person1属于People类
    //__proto__指向类People的原型prototype
    console.log(person1.__proto__ == People.prototype);//true
    

    Alt text

    原型链
    • 定义:一个实例要找属性,优先会去找自己的私有属性,如果自己的私有属性没有,那就通过__proto__找到自己所属类的原型上面的公有属性,如果公有属性还没有,继续通过__proto__找到自己的所属类的原型直到Object[基类]的原型上,一直找到基类还没有的话,直接返回undefined
    Object类和Function类

    Function类:

    • 所有的类都是通过函数的方式来创建,由此可以得知,所有的类(包括基类Object)都是函数类的一个实例
    • 判断一个实例是否属于一个类:intanceof
      console.log(Number instanceof Function); //true
      console.log(String instanceof Function); //true
      console.log(Object instanceof Function); //true
    • constructor:通过实例来调用这个方法,指向当前类本身
    • 万物皆对象,JS中的任何数据类型都可以通过proto
      Alt text
  • 相关阅读:
    Redis 之order set有序集合结构及命令详解
    Redis 之set集合结构及命令详解
    Redis 之list链表结构及命令详解
    Redis 之string结构及命令详解
    Redis 通用key操作命令
    Redis 在Linux下的安装
    Entity FrameWork 操作使用详情
    Linux 之常用操作指令详解
    Linux 之根目录介绍
    php 加密解密函数封装
  • 原文地址:https://www.cnblogs.com/kjz-jenny/p/9315241.html
Copyright © 2020-2023  润新知