Javascript知识点详解:对象、New命令、Object对象的相关方法

目录

对象

对象是什么

构造函数

new 命令

基本用法

new 命令的原理

new.target

Object.create() 创建实例对象

Object 对象的相关方法

Object.getPrototypeOf()

Object.setPrototypeOf()

Object.create()

Object.prototype.isPrototypeOf()

Object.prototype.__proto__

获取原型对象方法的比较

Object.getOwnPropertyNames()

Object.prototype.hasOwnProperty()

in 运算符和 for...in 循环

对象的拷贝


对象

JavaScript 语言具有很强的面向对象编程能力,本章介绍 JavaScript 面向对象编程的基础知识。

对象是什么

面向对象编程(Object Oriented Programming,缩写为 OOP)是目前主流的编程范式。它将真实世界各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟。

每一个对象都是功能中心,具有明确分工,可以完成接受信息、处理数据、发出信息等任务。对象可以复用,通过继承机制还可以定制,因此,面向对象编程具有灵活、代码可复用、高度模块化等特点,容易维护和开发,比起由一系列函数或指令组成的传统的过程式编程(procedural programming),更适合多人合作的大型软件项目。

那么,“对象”(object)到底是什么?我们从两个层次来理解。

(1)对象是单个实物的抽象。

一本书、一辆汽车、一个人都可以是对象,一个数据库、一张网页、一个远程服务器连接也可以是对象。当实物被抽象成对象,实物之间的关系就变成了对象之间的关系,从而就可以模拟现实情况,针对对象进行编程。

(2)对象是一个容器,封装了属性(property)和方法(method)。

属性是对象的状态,方法是对象的行为(完成某种任务)。

比如,我们可以把动物抽象为animal对象,使用“属性”记录具体是哪一种动物,使用“方法”表示动物的某种行为(奔跑、捕猎、休息等等)。

构造函数

面向对象编程的第一步,就是要生成对象。前面说过,对象是单个实物的抽象。通常需要一个模板,表示某一类实物的共同特征,然后对象根据这个模板生成。

典型的面向对象编程语言(比如 C++ 和 Java),都有“类”(class)这个概念。

所谓“类”就是对象的模板,对象就是“类”的实例。

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

JavaScript 语言使用构造函数(constructor)作为对象的模板(类似于类)。

所谓”构造函数”,就是专门用来生成实例对象的函数。它就是对象的模板,描述实例对象的基本结构。

一个构造函数,可以生成多个实例对象,这些实例对象都有相同的结构。

构造函数就是一个普通的函数,但具有自己的特征和用法。

var Vehicle = function () { //这里就定义了一个Vehicele构造函数,也就是类
    this.price = 1000;
};

上面代码中,Vehicle就是构造函数。

为了与普通函数区别,构造函数名字的第一个字母通常大写。

构造函数的特点有两个:

  • 函数体内部使用了this关键字,代表了所要生成的对象实例。

  • 生成对象的时候,必须使用new命令。

既然生成对象必须要使用new命令,那么我们来看看new的使用方法:

new 命令

基本用法

new命令的作用,就是执行构造函数,返回一个实例对象。

var Vehicle = function () { //创建一个构造函数,也就是类
    this.price = 1000; //这里的this指向后面生成的对象实例
};

var v = new Vehicle(); //这里使用 new关键字生成了一个实例对象
console.log(v.price)// 1000

上面代码通过new命令,让构造函数Vehicle生成一个实例对象,保存在变量v中。这个新生成的实例对象,从构造函数Vehicle得到了price属性。new命令执行时,构造函数内部的this,就代表了新生成的实例对象,this.price表示实例对象有一个price属性,值是1000。

使用new命令时,根据需要,构造函数也可以接受参数。

var Vehicle = function (p) { //构造函数在创建时,为函数指定了可以传入的参数p
  this.price = p;
};
​
var v = new Vehicle(500); //这里在实例化对象的时候给给函数传入了一个参数500

new命令本身就可以执行构造函数,所以后面的构造函数可以带括号,也可以不带括号。下面两行代码是等价的,但是为了表示这里是函数调用,推荐使用括号。

// 推荐的写法
var v = new Vehicle();
// 不推荐的写法
var v = new Vehicle;

一个很自然的问题是,如果忘了使用new命令,直接调用构造函数会发生什么事?

这种情况下,构造函数就变成了普通函数,并不会生成实例对象。

而且由于后面会说到的原因,this这时代表全局对象,将造成一些意想不到的结果。

var Vehicle = function () {
    this.price = 1000;
};
var v = Vehicle();
console.log(v);
console.log(price);

上面代码中,调用Vehicle构造函数时,忘了加上new命令,结果,变量v变成了undefined,而price属性变成了全局变量。

因此,应该非常小心,避免不使用new命令、直接调用构造函数。

为了保证构造函数必须与new命令一起使用。

一个解决办法是,构造函数内部使用严格模式,即第一行加上use strict。这样的话,一旦忘了使用new命令,直接调用构造函数就会报错。

另一个解决办法,构造函数内部判断是否使用new命令,如果发现没有使用,则直接返回一个实例对象。

function Fubar(foo, bar) {
    if (!(this instanceof Fubar)) {
        //instanceof :左边的是否是右边的类型
        return new Fubar(foo, bar);
        //如果this指向错误,那机会重新使用new创建一个构造函数
    }

    this._foo = foo;
    this._bar = bar;
}

console.log(Fubar(1, 2)._foo);// 1
console.log((new Fubar(1, 2))._foo);// 1

上面代码中的构造函数,不管加不加new命令,都会得到同样的结果。

new 命令的原理

使用new命令时,它后面的函数依次执行下面的步骤。

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

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

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

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

也就是说,构造函数内部,this指的是一个新生成的空对象,所有针对this的操作,都会发生在这个空对象上。构造函数之所以叫“构造函数”,就是说这个函数的目的,就是操作一个空对象(即this对象),将其“构造”为需要的样子。

构造函数中有无return的情况:

  • 如果构造函数内部有return语句,而且return后面跟着一个对象,new命令会返回return语句指定的对象;
  • 否则,就会不管return语句,返回this对象。
var Vehicle = function () {
  this.price = 1000; 
  return 1000;
};
​
(new Vehicle()) === 1000
//这里应该是this.price的值
// false

上面代码中,构造函数Vehiclereturn语句返回一个数值。

这时,new命令就会忽略这个return语句,返回“构造”后的this对象。

但是,如果return语句返回的是一个跟this无关的新对象,new命令会返回这个新对象,而不是this对象。

这一点需要特别引起注意。

var Vehicle = function (){
  this.price = 1000;
  return { price: 2000 };
};
(new Vehicle()).price
这里是return后面的值
// 2000

上面代码中,构造函数Vehiclereturn语句,返回的是一个新对象。new命令会返回这个对象,而不是this对象。

另一方面,如果对普通函数(内部没有this关键字的函数)使用new命令,则会返回一个空对象。

function getMessage() {
    return 'this is a message';
}

var msg = new getMessage();
console.log(msg);//{}
console.log(typeof msg);  // "object"

​​​​​​​

上面代码中,getMessage是一个普通函数,返回一个字符串。

对它使用new命令,会得到一个空对象。

这是因为new命令总是返回一个对象,要么是实例对象,要么是return语句指定的对象。本例中,return语句返回的是字符串,所以new命令就忽略了该语句。

new命令简化的内部流程,可以用下面的代码表示。

function _new(/* 构造函数 */ constructor, /* 构造函数参数 */ params) {
  // 将 arguments 对象转为数组
  var args = [].slice.call(arguments);
  // 取出构造函数
  var constructor = args.shift();
  // 创建一个空对象,继承构造函数的 prototype 属性
  var context = Object.create(constructor.prototype);
  // 执行构造函数
  var result = constructor.apply(context, args);
  // 如果返回结果是对象,就直接返回,否则返回 context 对象
  return (typeof result === 'object' && result != null) ? result : context;
}
​
// 实例
var actor = _new(Person, '张三', 28);

new.target

函数内部可以使用new.target属性。如果当前函数是new命令调用,new.target指向当前函数,否则为undefined

function f() {
  console.log(new.target === f);
}
​
f() // false
new f() // true

使用这个属性,可以判断函数调用的时候,是否使用new命令。

​
function f() {
  if (!new.target) {
    throw new Error('请使用 new 命令调用!');
  }
  // ...
}
f() // Uncaught Error: 请使用 new 命令调用!

上面代码中,构造函数f调用时,没有使用new命令,就抛出一个错误。

Object.create() 创建实例对象

构造函数作为模板,可以生成实例对象。但是,有时拿不到构造函数,只能拿到一个现有的对象。我们希望以这个现有的对象作为模板,生成新的实例对象,这时就可以使用Object.create()方法。

var person1 = {
    name: '张三',
    age: 38,
    greeting: function () {
        console.log('Hi! I\'m ' + this.name + '.');
    }
};

var person2 = Object.create(person1);
//这里使用person1作为魔板,创建一个person2实例对象

console.log(person2.name) // 张三
console.log(person2.greeting()) // Hi! I'm 张三.

上面代码中,对象person1person2的模板,后者继承了前者的属性和方法。

Object 对象的相关方法

JavaScript 在Object对象上面,提供了很多相关方法,处理面向对象编程的相关操作。本章介绍这些方法。

Object.getPrototypeOf()

Object.getPrototypeOf方法返回参数对象的原型。这是获取原型对象的标准方法。

var F = function () { }; //构造函数F
var f = new F(); 实例化对象f
Object.getPrototypeOf(f) === F.prototype // true
//这里判断F是不是f对象的原型,很明显是的

上面代码中,实例对象f的原型是F.prototype

下面是几种特殊对象的原型:

// 空对象的原型是 Object.prototype
Object.getPrototypeOf({}) === Object.prototype // true
​
// Object.prototype 的原型是 null
Object.getPrototypeOf(Object.prototype) === null // true
​
// 函数的原型是 Function.prototype
function f() {}
Object.getPrototypeOf(f) === Function.prototype // true

Object.setPrototypeOf()

Object.setPrototypeOf方法为参数对象设置原型,返回该参数对象。

它接受两个参数,第一个是现有对象,第二个是原型对象。

var a = {};
var b = { x: 1 };
Object.setPrototypeOf(a, b);
//这里将现有的对象b作为a对象的原型
Object.getPrototypeOf(a) === b // true
a.x 
// 这里会打印1,因为a的原型,也就是b有这个变量

上面代码中,Object.setPrototypeOf方法将对象a的原型,设置为对象b,因此a可以共享b的属性。

new命令可以使用Object.setPrototypeOf方法模拟。

var F = function () {
    this.foo = 'bar';
};

var f = new F();
// 等同于
console.log(f.foo);//bar
var f = Object.setPrototypeOf({}, F.prototype);
//这时使用setPrototypeOf方法,将f的原型设置为F
console.log(f.foo);//undefined

F.call(f);
//这是将F构造函数绑定到了f上,那么F构造函数中的this会指向f
console.log(f.foo); //bar

上面代码中,new命令新建实例对象,其实可以分成两步。

第一步,将一个空对象的原型设为构造函数的prototype属性(上例是F.prototype);

第二步,将构造函数内部的this绑定这个空对象,然后执行构造函数,使得定义在this上面的方法和属性(上例是this.foo),都转移到这个空对象上。

Object.create()

这个方法前面已经介绍过了,这里不再赘述

下面三种方式生成的新对象是等价的。

var obj1 = Object.create({});
var obj2 = Object.create(Object.prototype);
var obj3 = new Object();

如果想要生成一个不继承任何属性(比如没有toString()valueOf()方法)的对象,可以将Object.create()的参数设为null

var obj = Object.create(null);
​
obj.valueOf()
// TypeError: Object [object Object] has no method 'valueOf'

上面代码中,对象obj的原型是null,它就不具备一些定义在Object.prototype对象上面的属性,比如valueOf()方法。

使用Object.create()方法的时候,必须提供对象原型,即参数不能为空,或者不是对象,否则会报错。

Object.create()
// TypeError: Object prototype may only be an Object or null
Object.create(123)
// TypeError: Object prototype may only be an Object or null

Object.create()方法生成的对象,继承了它的原型对象的构造函数。

function A() {}
var a = new A();
var b = Object.create(a);
​
b.constructor === A // true
b instanceof A // true

上面代码中,b对象的原型是a对象,因此继承了a对象的构造函数A

Object.prototype.isPrototypeOf()

实例对象的isPrototypeOf方法,用来判断该对象是否为参数对象的原型。

var o1 = {};
var o2 = Object.create(o1);
var o3 = Object.create(o2);

console.log(o2.isPrototypeOf(o3)) // true
console.log(o1.isPrototypeOf(o3)) // true

​​​​​​​

上面代码中,o1o2都是o3的原型。这表明只要实例对象处在参数对象的原型链上,isPrototypeOf方法都返回true

Object.prototype.isPrototypeOf({}) // true
Object.prototype.isPrototypeOf([]) // true
Object.prototype.isPrototypeOf(/xyz/) // true
Object.prototype.isPrototypeOf(Object.create(null)) // false

上面代码中,由于Object.prototype处于原型链的最顶端,所以对各种实例都返回true,只有直接继承自null的对象除外。

Object.prototype.__proto__

实例对象的__proto__属性(前后各两个下划线),返回该对象的原型。该属性可读写。

var obj = {};
var p = {};
obj.__proto__ = p;
console.log(Object.getPrototypeOf(obj) === p) // true

上面代码通过__proto__属性,将p对象设为obj对象的原型。

根据语言标准,__proto__属性只有浏览器才需要部署,其他环境可以没有这个属性。它前后的两根下划线,表明它本质是一个内部属性,不应该对使用者暴露。因此,应该尽量少用这个属性,而是用Object.getPrototypeOf()Object.setPrototypeOf(),进行原型对象的读写操作。

获取原型对象方法的比较

如前所述,__proto__属性指向当前对象的原型对象,即构造函数的prototype属性。

var obj = new Object();

obj.__proto__ === Object.prototype
// true
obj.__proto__ === obj.constructor.prototype
// true
Object.prototype === obj.constructor.prototype
//true

上面代码首先新建了一个对象obj,它的__proto__属性,指向构造函数(Objectobj.constructor)的prototype属性。

因此,获取实例对象obj的原型对象,有三种方法:

  • obj.__proto__

  • obj.constructor.prototype

  • Object.getPrototypeOf(obj)

上面三种方法之中,前两种都不是很可靠。

__proto__属性只有浏览器才需要部署,其他环境可以不部署。

obj.constructor.prototype在手动改变原型对象时,可能会失效。

因此,推荐使用第三种Object.getPrototypeOf方法,获取原型对象。

Object.getOwnPropertyNames()

Object.getOwnPropertyNames方法返回一个数组,成员是参数对象本身的所有属性的键名,不包含继承的属性键名。

Object.getOwnPropertyNames(Date)
// ["parse", "arguments", "UTC", "caller", "name", "prototype", "now", "length"]

上面代码中,Object.getOwnPropertyNames方法返回Date所有自身的属性名。

对象本身的属性之中,有的是可以遍历的(enumerable),有的是不可以遍历的。Object.getOwnPropertyNames方法返回所有键名,不管是否可以遍历。

只获取那些可以遍历的属性,使用Object.keys方法。

Object.keys(Date) // []

上面代码表明,Date对象所有自身的属性,都是不可以遍历的。

Object.prototype.hasOwnProperty()

对象实例的hasOwnProperty方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。

Date.hasOwnProperty('length') // true 
//即 length是自己原型链上的属性,
Date.hasOwnProperty('toString') // false
//即,toString不是自己原型链上的属性,

上面代码表明,Date.length(构造函数Date可以接受多少个参数)是Date自身的属性,Date.toString是继承的属性。

另外,hasOwnProperty方法是 JavaScript 之中唯一一个处理对象属性时,不会遍历原型链的方法。

in 运算符和 for...in 循环

in运算符返回一个布尔值,表示一个对象是否具有某个属性。它不区分该属性是对象自身的属性,还是继承的属性。

'length' in Date // true
'toString' in Date // true

in运算符常用于检查一个属性是否存在。

获得对象的所有可遍历属性(不管是自身的还是继承的),可以使用for...in循环。

var o1 = { p1: 123 };
​
var o2 = Object.create(o1, {
  p2: { value: "abc", enumerable: true }
});
​
for (p in o2) {
  console.info(p);
}
// p2
// p1

上面代码中,对象o2p2属性是自身的,p1属性是继承的。这两个属性都会被for...in循环遍历。

对象的拷贝

如果要拷贝一个对象,需要做到下面两件事情。

  • 确保拷贝后的对象,与原对象具有同样的原型。

  • 确保拷贝后的对象,与原对象具有同样的实例属性。

下面就是根据上面两点,实现的对象拷贝函数。

function copyObject(orig) {
  var copy = Object.create(Object.getPrototypeOf(orig));
  copyOwnPropertiesFrom(copy, orig);
  return copy;
}
​
function copyOwnPropertiesFrom(target, source) {
  Object
    .getOwnPropertyNames(source)
    .forEach(function (propKey) {
      var desc = Object.getOwnPropertyDescriptor(source, propKey);
      Object.defineProperty(target, propKey, desc);
    });
  return target;
}

另一种更简单的写法,是利用 ES2017 才引入标准的Object.getOwnPropertyDescriptors方法。

function copyObject(orig) {
  return Object.create(
    Object.getPrototypeOf(orig),
    Object.getOwnPropertyDescriptors(orig)
  );
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/123230.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue3.0 声明式导航,编程式导航,路由,路由拦截案例

项目结构 App.vue&#xff1a;根组件 <template><div><router-view></router-view><Tabbar></Tabbar></div> </template> <script setup> import Tabbar from ../src/views/Tabbar.vue; //底部选项卡 import Home from…

预约按摩app小程序开发搭建;

预约按摩app小程序开发搭建&#xff1b; 后端&#xff1a;系统后端使用PHP语言开发 前端&#xff1a;前端使用uniapp进行前后端分离开发&#xff0c;支持&#xff08;公中号、小程序、APP&#xff09;。 用户端功能模块&#xff1a;技师选择、预约服务、优惠券、订单、技师服…

【快速使用ShardingJDBC的哈希分片策略进行分表】

文章目录 &#x1f50a;博主介绍&#x1f964;本文内容&#x1f34a;1.引入maven依赖&#x1f34a;2.启动类上添加注解MapperScan&#x1f34a;3.添加application.properties配置&#x1f34a;4.普通的自定义实体类&#x1f34a;5.写个测试类验证一下&#x1f34a;6.控制台打印…

【原创】java+jsp+servlet简单图书管理系统设计与实现

摘要&#xff1a; 图书管理系统是一个专门针对图书馆管理而设计的系统&#xff0c;它可以帮助图书管理员有效的对图书进行管理&#xff0c;在图书管理系统的设计中&#xff0c;首先要考虑的是系统的需求分析&#xff0c;该系统的设计与实现涉及多个方面&#xff0c;包括数据库…

RSA 2048位算法的主要参数N,E,P,Q,DP,DQ,Qinv,D分别是什么意思 哪个是通常所说的公钥与私钥 -安全行业基础篇5

非对称加密算法RSA 在RSA 2048位算法中&#xff0c;常见的参数N、E、P、Q、DP、DQ、Qinv和D代表以下含义&#xff1a; N&#xff08;Modulus&#xff09;&#xff1a;模数&#xff0c;是两个大素数P和Q的乘积。N的长度决定了RSA算法的安全性。 E&#xff08;Public Exponent&a…

09-MySQL主从复制

01-主从复制原理 MySQL主从复制是一种用于实现数据备份、读写分离和扩展性的技术。它基于二进制日志&#xff08;Binary Log&#xff09;来将主数据库上的更改操作同步到一个或多个从数据库。 MySQL主从复制的基本原理如下&#xff1a; 主服务器&#xff08;Master&#xff0…

数据结构-栈和队列力扣题

目录 有效的括号 用队列实现栈 用栈实现队列 设计循环队列 有效的括号 题目链接&#xff1a;力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 这道题可以用栈来解决&#xff0c;先让字符串中的左括号 ( &#xff0c; [ &#xff0c; { 入栈&#xff0c;s指向字符串下…

U-Mail信创邮件系统解决方案

近年来&#xff0c;在国家政策的大力引导和自身数字化转型需求驱动下&#xff0c;国产化成为国内数字化发展道路上的关键词&#xff0c;企业不断加强自主创新能力&#xff0c;进行信创建设&#xff0c;实现软硬件系统国产化替代&#xff0c;已成为大势所趋。邮件系统作为企业管…

代码随想录训练营Day1:二分查找与移除元素

本专栏内容为&#xff1a;代码随想录训练营学习专栏&#xff0c;用于记录训练营的学习经验分享与总结。 文档讲解&#xff1a;代码随想录 视频讲解&#xff1a;二分查找与移除元素 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;C &#x1f69a…

某卢小说网站登录密码逆向

js逆向&#xff0c;今晚找了一个小说网站&#xff0c;分析一下登录密码的解密逆向过程&#xff0c;过程不是很难&#xff0c;分享下 学习网站aHR0cHM6Ly91LmZhbG9vLmNvbS9yZWdpc3QvbG9naW4uYXNweA 这个就是加密后的密码&#xff0c;今晚就逆向它&#xff0c;其他参数暂时不研究…

python+pytorch人脸表情识别

概述 基于深度学习的人脸表情识别&#xff0c;数据集采用公开数据集fer2013&#xff0c;可直接运行&#xff0c;效果良好&#xff0c;可根据需求修改训练代码&#xff0c;自己训练模型。 详细 一、概述 本项目以PyTorch为框架&#xff0c;搭建卷积神经网络模型&#xff0c;训…

【中间件篇-Redis缓存数据库02】Redis高级特性和应用(慢查询、Pipeline、事务、Lua)

Redis高级特性和应用(慢查询、Pipeline、事务、Lua) Redis的慢查询 许多存储系统&#xff08;例如 MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作。所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间&#xff0c;当超过预设阀值,就将这条命令的相关…

腾讯云双11优惠活动有哪些?详细攻略来了!

2023年腾讯云双11大促活动正在火热进行中&#xff0c;百款热门云产品11.11云上盛惠&#xff0c;领折上折代金券最高再省9999元&#xff0c;助力开发者轻松上云&#xff01; 一、腾讯云双11活动入口 活动地址&#xff1a;点此直达 二、腾讯云双11活动时间 即日起至2023-11-30…

基于SSM的电动车上牌管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

2012年计网408

第33题 在 TCP/IP 体系结构中, 直接为 ICMP 提供服务的协议是()A. PPPB. IPC. UDPD. TCP 本题考察TCP/IP体系结构中直接为ICMP协议提供服务的协议。如图所示。这是TCP/IP的四层体系结构。网际层的IP协议是整个体系结构中的核心协议&#xff0c;用于网络互联。网际控制报文协议…

MongoDB副本集特点验证

MongoDB副本集特点验证 mogodb副本集概述副本集搭建副本集结构验证结果源码地址 mogodb副本集概述 MongoDB副本集是将数据同步在多个服务器的过程。 复制提供了数据的冗余备份&#xff0c;并在多个服务器上存储数据副本&#xff0c;提高了数据的可用性&#xff0c; 并可以保证…

To create the 45th Olympic logo by using CSS

You are required to create the 45th Olympic logo by using CSS. The logo is composed of five rings and three rectangles with rounded corners. The HTML code has been given. It is not allowed to add, edit, or delete any HTML elements. 私信完整源码 <!DOCT…

MFC-TCP网络编程服务端-Socket

目录 1、通过Socket建立服务端&#xff1a; 2、UI设计&#xff1a; 3、代码的实现&#xff1a; &#xff08;1&#xff09;、CListenSocket类 &#xff08;2&#xff09;、CConnectSocket类 &#xff08;3&#xff09;、CTcpServerDlg类 1、通过Socket建立服务端&#xff…

分享一本让你真正理解深度学习的书

关注微信公众号&#xff1a;人工智能大讲堂&#xff0c;后台回复udl获取pdf文档。 今天要分享的书是Understanding Deep Learning&#xff0c;作者是西蒙普林斯&#xff0c;英国巴斯大学的荣誉教授&#xff0c;其个人学术能力相当强大&#xff0c;在AI领域有着深厚的学术造诣。…

网络唤醒(Wake-on-LAN, WOL)

远程唤醒最简单的方法&#xff1a;DDNSTOOpenwrt网络唤醒&#xff0c;完美实现。 原帖-远程唤醒_超详细windows设置远程唤醒wol远程连接&#xff08;远程开机&#xff09; WOL Web# 访问 Wake on Lan Over The Interweb by Depicus 可以无需借助软件很方便的从网页前端唤醒远…