搜索
首页web前端js教程JS面向对象的详细介绍(二)

JS面向对象的详细介绍(二)

Jun 29, 2017 pm 01:37 PM
javascript对象笔记

菜单导航,《JS面向对象笔记一》,  参考书籍:阮一峰之《JavaScript标准参考教程》

一、构造函数和new命令

二、this关键字

三、构造函数和new命令

四、构造函数和new命令

五、构造函数和new命令

六、构造函数和new命令

七、构造函数和new命令

八、构造函数和new命令

 

一、构造函数和new命令

1、构造函数

  • JavaScript语言的对象体系,不是基于“类”的,而是基于构造函数(constructor)和原型链(prototype)

  • 为了与普通函数区别,构造函数名字的第一个字母通常大写,比如:  var Person = function(){  this.name = '王大锤';  }

  • 构造函数的特点: 
           a、函数体内部使用了this关键字,代表了所要生成的对象实例;
       b、生成对象的时候,必需用new命令调用此构造函数

2、new 

  作用:就是执行构造函数,返回一个实例对象 

var Person = function(name, age){this.name = name;this.age = age;this.email = 'cnblogs@sina.com';this.eat = function(){
        console.log(this.name + ' is eating noodles');
    }
}var per = new Person('王大锤', 18);
console.log(per.name + ', ' + per.age + ', ' + per.email); //王大锤, 18, cnblogs@sina.comper.eat();  //王大锤 is eating noodles

执行new命令时的原理步骤:

  1. 创建一个空对象,作为将要返回的对象实例

  2. 将这个空对象的原型,指向构造函数的prototype属性

  3. 将这个空对象赋值给函数内部的this关键字

  4. 开始执行构造函数内部的代码

注意点:当构造函数里面有return关键字时,如果返回的是非对象,new命令会忽略返回的信息,最后返回时构造之后的this对象;
  如果return返回的是与this无关的新对象,则最后new命令会返回新对象,而不是this对象。示例代码:

console.log('---- 返回字符串 start ----');var Person = function(){this.name = '王大锤';return '罗小虎';
}var per = new Person();for (var item in per){
    console.log( item + ': ' + per[item] );
}//---- 返回字符串 start ----//name: 王大锤console.log('----- 返回对象 start ----');var PersonTwo = function(){this.name = '倚天剑';return {nickname: '屠龙刀', price: 9999 };
}var per2 = new PersonTwo();for (var item in per2){
    console.log(item + ': ' + per2[item]);
}//----- 返回对象 start ----//nickname: 屠龙刀//price: 9999
View Code

 

如果调用构造函数的时候,忘记使用new关键字,则构造函数里面的this为全局对象window,属性也会变成全局属性,

则被构造函数赋值的变量不再是一个对象,而是一个未定义的变量,js不允许给undefined添加属性,所以调用undefined的属性会报错。

示例:

var Person = function(){ 
    console.log( this == window );  //truethis.price = 5188; 
}var per = Person();
console.log(price); //5188console.log(per);  //undefinedconsole.log('......_-_'); //......_-_console.log(per.price); //Uncaught TypeError: Cannot read property 'helloPrice' of undefined
View Code

为了规避忘记new关键字现象,有一种解决方式,就是在函数内部第一行加上 : 'use strict';

表示函数使用严格模式,函数内部的this不能指向全局对象window, 默认为undefined, 导致不加new调用会报错

var Person = function(){ 'use strict';
    console.log( this );  //undefinedthis.price = 5188; //Uncaught TypeError: Cannot set property 'helloPrice' of undefined}var per = Person();
View Code

另外一种解决方式,就是在函数内部手动添加new命令:

var Person = function(){ //先判断this是否为Person的实例对象,不是就new一个if (!(this instanceof Person)){return new Person();
    }
    console.log( this );  //Person {}this.price = 5188; 
}var per = Person(); 
console.log(per.price); //5188
View Code

 

 

二、this关键字

var Person = function(){
    console.log('1111'); 
    console.log(this); this.name = '王大锤';this.age = 18;this.run = function(){
        console.log('this is Person的实例对象吗:' + (this instanceof Person) ); 
        console.log(this); 
    }
}var per = new Person();
per.run();/* 打印日志:
1111
Person {}
this is Person的实例对象吗:true
Person {name: "王大锤", age: 18, run: function}*/console.log('---------------');var Employ = {
    email: 'cnblogs@sina.com',
    name: '赵日天',
    eat: function(){
        console.log(this);
    }
}

console.log(Employ.email + ', ' + Employ.name);
Employ.eat();/* 打印日志:
---------------
cnblogs@sina.com, 赵日天
Object {email: "cnblogs@sina.com", name: "赵日天", eat: function}*/
View Code

1、this总是返回一个对象,返回属性或方法当前所在的对象, 如上示例代码

2、对象的属性可以赋值给另一个对象,即属性所在的当前对象可变化,this的指向可变化

var A = { 
    name: '王大锤', 
    getInfo: function(){return '姓名:' + this.name;
    } 
}var B = { name: '赵日天' };

B.getInfo = A.getInfo;
console.log( B.getInfo() ); //姓名:赵日天//A.getInfo属性赋给B, 于是B.getInfo就表示getInfo方法所在的当前对象是B, 所以这时的this.name就指向B.name
View Code

 3、由于this指向的可变化性,在层级比较多的函数中需要注意使用this。一般来说,在多层函数中需要使用this时,设置一个变量来固定this的值,然后在内层函数中这个变量。

示例1:多层中的this

//1、多层中的this (错误演示)var o = {
    f1: function(){
        console.log(this); //这个this指的是o对象var f2 = function(){
            console.log(this);
        }();//由于写法是(function(){ })() 格式, 则f2中的this指的是顶层对象window    }
}

o.f1();/* 打印日志:
Object {f1: function}

Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}*///2、上面代码的另一种写法(相同效果)var temp = function(){
    console.log(this);
}var o = {
    f1: function(){
        console.log(this); //这个this指o对象var f2 = temp(); //temp()中的this指向顶层对象window    }
}
o.f1(); 
/* 打印日志
Object {f1: function}

Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}*///表示上面两种写法是一样的效果,this的错误演示//3、多层中this的正确使用:使用一个变量来固定this对象,然后在内层中调用该变量var o = {
    f1: function(){
        console.log(this); //o对象var that = this;var f2 = function(){
            console.log(that); //这个that指向o对象        }();
    }
}
o.f1();/* 打印日志:
Object {f1: function}
Object {f1: function}*/
View Code

示例2: 数组遍历中的this

//1、多层中数组遍历中this的使用 (错误演示)var obj = {
    email: '大锤@sina.com', 
    arr: ['aaa', 'bbb', '333'],
    fun: function(){//第一个this指的是obj对象this.arr.forEach(function(item){//这个this指的是顶层对象window, 由于window没有email变量,则为undefinedconsole.log(this.email + ': ' + item);
        });
    }
}

obj.fun(); 
/* 打印结果:
undefined: aaa
undefined: bbb
undefined: 333 *///2、多层中数组遍历中this的使用 (正确演示,第一种写法)var obj = {
    email: '大锤@sina.com', 
    arr: ['aaa', 'bbb', '333'],
    fun: function(){//第一个this指的是obj对象var that = this; //将this用变量固定下来this.arr.forEach(function(item){//这个that指的是对象objconsole.log(that.email + ': ' + item);
        });
    }
}
obj.fun(); //调用/* 打印日志:
大锤@sina.com: aaa
大锤@sina.com: bbb
大锤@sina.com: 333 *///3、多层中数组遍历中this正确使用第二种写法:将this作为forEach方法的第二个参数,固定循环中的运行环境var obj = {
    email: '大锤@sina.com', 
    arr: ['aaa', 'bbb', '333'],
    fun: function(){//第一个this指的是obj对象this.arr.forEach(function(item){//这个this从来自参数this, 指向obj对象console.log(this.email + ': ' + item);
        }, this);
    }
}
obj.fun(); //调用/* 打印日志:
大锤@sina.com: aaa
大锤@sina.com: bbb
大锤@sina.com: 333 */
View Code

 

4、关于js提供的call、apply、bind方法对this的固定和切换的用法

  1)、function.prototype.call(): 函数实例的call方法,可以指定函数内部this的指向(即函数执行时所在的作用域),然后在所指定的作用域中,调用该函数。
  如果call(args)里面的参数不传,或者为null、undefined、window, 则默认传入全局顶级对象window;
  如果call里面的参数传入自定义对象obj, 则函数内部的this指向自定义对象obj, 在obj作用域中运行该函数

var obj = {};var f = function(){
    console.log(this);return this;
}

console.log('....start.....');
f();
f.call();
f.call(null);
f.call(undefined);
f.call(window);
console.log('**** call方法的参数如果为空、null和undefined, 则默认传入全局等级window;如果call方法传入自定义对象obj,则函数f会在对象obj的作用域中运行 ****');
f.call(obj);
console.log('.....end.....');/* 打印日志:
....start.....
Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}
Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}
Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}
Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}
Window {stop: function, open: function, alert: function, confirm: function, prompt: function…}
**** call方法的参数如果为空、null和undefined, 则默认传入全局等级window;如果call方法传入自定义对象obj,则函数f会在对象obj的作用域中运行 ****
Object {}
.....end.....*/
View Code

 

以上是JS面向对象的详细介绍(二)的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
Python vs. JavaScript:学习曲线和易用性Python vs. JavaScript:学习曲线和易用性Apr 16, 2025 am 12:12 AM

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

Python vs. JavaScript:社区,图书馆和资源Python vs. JavaScript:社区,图书馆和资源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社区、库和资源方面的对比各有优劣。1)Python社区友好,适合初学者,但前端开发资源不如JavaScript丰富。2)Python在数据科学和机器学习库方面强大,JavaScript则在前端开发库和框架上更胜一筹。3)两者的学习资源都丰富,但Python适合从官方文档开始,JavaScript则以MDNWebDocs为佳。选择应基于项目需求和个人兴趣。

从C/C到JavaScript:所有工作方式从C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

JavaScript引擎:比较实施JavaScript引擎:比较实施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

超越浏览器:现实世界中的JavaScript超越浏览器:现实世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在现实世界中的应用包括服务器端编程、移动应用开发和物联网控制:1.通过Node.js实现服务器端编程,适用于高并发请求处理。2.通过ReactNative进行移动应用开发,支持跨平台部署。3.通过Johnny-Five库用于物联网设备控制,适用于硬件交互。

使用Next.js(后端集成)构建多租户SaaS应用程序使用Next.js(后端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:23 AM

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务

如何使用Next.js(前端集成)构建多租户SaaS应用程序如何使用Next.js(前端集成)构建多租户SaaS应用程序Apr 11, 2025 am 08:22 AM

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

JavaScript:探索网络语言的多功能性JavaScript:探索网络语言的多功能性Apr 11, 2025 am 12:01 AM

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器