首页 > 试题广场 >

填写内容让下面代码支持a.name = “name1”; b

[填空题]
填写内容让下面代码支持a.name = “name1”; b.name = “name2”;
function obj(name){
    1
}
obj.2= "name2";
var a = obj("name1");
var b = new obj;
推荐
// 我讲得好啰嗦..
function obj(name){
    if(name){
    	this.name = name;
    }
    return this;
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj;

console.log(a.name); // name1
console.log(window.name); // name1
console.log(b.name); // name2

//一般函数直接调用,默认this执行全局window|global
//通过obj('name1')调用,返回this引用,并传给a, 此时a等于window对象,即可输出属性name值

//new操作, new obj 等价于 new obj() ,实例化一个对象,这时this指向obj,要拿到b.name的值
//需要保证name属性存在,属性查找原则是先查找当前实例有没有属性,如果有就直接使用,如果没有就到原型上面找,再没有就接着原型链一步一步,这里为了和a.name作属性区别,使用了if(name)有条件地构建this的属性name
//所以,现在实例name属性提供给a使用,原型上的name提供给b使用。

//两个变体
function obj(name){
    //if(name){
    	this.name = name;
    //}
    return this;
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj;

console.log(a.name);//name1
console.log(window.name);//name1
console.log(b.name);//undefined
// 这时b实例已经有属性name,但参数name为undefined ,所以
// 这时可以把,this.name属性删掉,这样就能去原型找name了
function obj(name){
    //if(name){
    	this.name = name;
    //}
    return this;
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj;

console.log(a.name);//name1
console.log(window.name);//name1
delete b.name;
console.log(b.name);//name2


// 再试试 new obj('myName') 传个参数
function obj(name){
    //if(name){
    	this.name = name;
    //}
    return this;
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj('myName');

console.log(a.name);//name1
console.log(window.name);//name1
console.log(b.name);//myName











编辑于 2015-12-15 11:01:58 回复(25)
答案不完美。var a = obj("name1");不通过new操作符调用函数时,函数里面的this就指向全局对象了(浏览器环境下就是window),所以a、window指向的都是同一个全局对象。如果 var c = obj("name3")时,a的值会改变成name3.因为此时a、c都指向window对象。
提供另一种方式:
function obj(name){
if (name) {
var obj = {};
obj.name = name;
return obj;
}
}
obj.prototype.name = "name2";
var a = obj("name1");
var b = new obj;
发表于 2016-05-13 15:35:07 回复(4)
1.this
this对象 引用的是函数据以执行的环境对象。
在全局作用域中调用函数,this指向window;当函数被作为某个对象的方法调用时,this指向 此对象; 匿名函数的执行环境具有全局性,其this对象通常指向window。
通过将外部作用域的this对象保存到一个闭包可以访问的变量里 闭包,可以让闭包访问非全局变量的值。
call()、apply()可改变函数执行环境,从而改变this指向。
2.prototype
(1)原型对象、构造函数、对象实例之间的关系:
创建新函数,会根据一组特定的规则为该函数创建一个prototype属性,该属性指向函数的原型对象;
默认情况下,所有原型对象会自己动获取一个constructor属性,该属性指向prototype属性所在函数;
调用构造函数创建新实例,该实例内部包含一个内部属性[[Prototype]]指向构造函数的原型对象。
注意:
连接存在于实例与构造函数的原型对象之间,而不是存在于实例与构造函数之间。
(2)属性搜索
每当代码读取某个对象的的某个属性的时候,都会执行一次搜索,目标是具有给定名字的属性。搜索首先从对象实例本身开始,若找到则返回该属性的值,若找不到则继续搜索指针指向的原型对象。
(3)属性 设置
设置原型对象属性:
Object.prototype.prototypeName=prototypeValue;
为对象实例添加 属性:
Object.propertyName=propertyValue;
为对象实例添加一个属性时,这个属性会屏蔽原型对象中保存的同名属性。
3.使用new操作符调用函数创建实例的执行步骤
(1)创建一个新对象;
(2)将函数的作用域赋给新对象(this指向新对象);
(3)执行函数中的代码;
(4)返回新对象。
4.代码解析
//创建全局函数
function obj(name){
    if(name){
        this.name = name;
    }
    return this;//返回this引用
}
obj.prototype.name = "name2";//设置原型对象
var a = obj("name1");//直接调用函数,this等于window,a等于window。
var b = new obj;//等价于var b = new obj();调用函数实例化对象,this指向obj。

编辑于 2016-07-26 16:39:14 回复(3)
答案 1 是错的会污染全局变量也还意思拿出来
这题的本意应该是如何区分函数和构造函数
下面这样就可以了
if (!(this instanceof obj)) {return {'name':name}} else {if (name!==undefined) this.name=name}
ES6 的话可以用 new.target 来检测
编辑于 2016-12-13 19:41:15 回复(0)
不推荐答一。 function obj(name){ if(this === window){ var obj = {}; obj.name = name; return obj; } this.hehe = name; } obj.prototype.name = "name2"; var a = obj("name1"); var b = new obj; var c = new obj("name3"); console.log(a.name); // name1 console.log(b.name); // name2 console.log(c.name); // name2 console.log(c.hehe); // name3
发表于 2016-12-30 09:48:39 回复(0)
主要问题是在(1),讨论区里有两种方法。 方法1: if(name){ var obj ={}; obj.name = "name1"; return obj; } 方法2: if(name){ this.name =name; } return this; 从结果来看,两种方法都是可行的。 但是方法2并不妥:普通调用函数得时,在非严格模式下,this是绑定到全局对象window对象上的,因此方法2中this.name是在windiw对象上添加name属性,并把window对象返回。因此a实际上是windiw对象的引用,a.name就是在window对象上查找name变量,因为在window对象上赋值了当然是可以查找到name变量的。 一般要避免污染全局变量,在这里其实应该避免。而方法1,创建了一个新对象,并返回这个新对象,减少了全局变量的创建,更可取。
发表于 2016-05-14 21:16:06 回复(0)
1 if(name) { return { name : name } }
2 prototype.name

让obj的原型链上保存name2,
如果该函数接收参数则返回对象
编辑于 2017-07-20 16:34:08 回复(0)
有点不太懂返回this什么意思
发表于 2017-03-24 10:00:38 回复(1)

就是关于《JS高程》中创建对象的两种方式的应用。一种为构造函数模式,另一种为原型模式。

本题中,为了使a,b的name属性值不同,需要通过在构造函数增加判断,如果有参数传入,则采用构造函数模式,

function obj(name){
   var o=new Object();
   o.name=name;
return o;
}
obj.prototype.name='name2';
a.obj('name1');

因为实例中已经定义了name属性值,所以将原型中的覆盖掉了,a.name=='name1'如果没有参数传入,实际则为下列形式

function obj(name){
}
obj.prototype.name='name2';
var b=new obj;

根据原型模式,易知b.name=='name2'

编辑于 2017-01-01 22:42:49 回复(0)
这里的obj原型是一个对象:
[ object Object ] {
  name
: "name2"
}
obj的类型是function对象,这个function对象的原型中有一个成员叫name,本身的定义中恰好也有一个成员叫name;
原则上本身定义的name会覆盖原型中的name属性(类似于C++派生类的override),但是因为使用了if(name)判断,所以也有可能不会定义自身的name属性,假如程序是:
function obj(name){
    //if(name){
        this.name = name;
    //}
    return this;
}
输出的b.name的结果是undefined,并不会沿着原型链找到“name2”。

vara = obj("name1");
这样使用obj的话相当于定义了全局window中的name属性(因为this指向全局对象),a.name=window.name。
varb = newobj;
这里因为没有形参,且this指向实例化的对象,因为name没定义,所以沿着原型链查找name,最终b.name='name2'。

编辑于 2016-03-17 12:38:18 回复(0)
参考答案到底啥意思?到底不对啊,我这回答跟参考答案一毛一样,居然说我错了
发表于 2023-03-14 23:01:50 回复(0)
发表于 2021-10-31 13:54:51 回复(0)

第一步里要显式返回this

发表于 2019-02-22 13:26:50 回复(0)
 if(name){return {"name": name}}
应该可以在不new的情况成立吧
发表于 2018-10-21 00:23:21 回复(0)
给绕进去了。。。。我的做法是如果传入name就返回一个新的函数对象,结果忘记了函数中的this是window对象
发表于 2018-02-25 22:40:17 回复(0)
 function obj(name) {
    if( !(this instanceof obj) ) {
        return new obj(name)
    }
    this.name = name
}
obj.prototype.name="name2'
var a = obj('name1')
var b = new obj
console.log(a.name)
console.log(b.name)
发表于 2017-10-12 15:49:38 回复(0)
// this指针指向不同
function obj(name){if(this === window){return {name:name}}}
编辑于 2017-09-07 16:12:03 回复(0)
function obj(name){
    if(name){
        if(this===window){
            //直接调用函数
            return new obj(name);
        }else{
            //不同于函数调用 new 在无return时默认返回实例
            this.name=name;
        }
    }
}

编辑于 2017-03-31 16:43:15 回复(0)
Pal头像 Pal
function obj(name){
    if(!(this instanceof obj)){
        //如果this是window
        return new obj(name);
}
    return this.name
}
这样写难道不行吗?

发表于 2017-03-20 17:39:12 回复(0)
function obj(name){
     if(arguments.length!=0){
           return {name:name}
    }
}
obj. prototype.name = "name2";
var a = obj("name1");
var b = new obj;
发表于 2017-03-15 20:00:53 回复(0)
prototype prototype prototype
发表于 2017-03-08 16:26:55 回复(0)